/*=============================================================================
 D3DTexture.cpp : Direct3D specific texture manager implementation.
 Copyright (c) 2001 Crytek Studios. All Rights Reserved.
 
 Revision history:
 * Created by Honitch Andrey
 
 =============================================================================*/
 
 #include "StdAfx.h"
 #include "DriverD3D.h"
 #include "D3DTexture.h"
 #include "I3DEngine.h"
 #include "StringUtils.h"
 #include <ImageExtensionHelper.h>
 #include <IFlashPlayer.h>
 #include "BitFiddling.h"		// ConvertBlock3DcToDXT5()
 #include "D3DStereo.h"
 #include "../Common/PostProcess/PostProcessUtils.h"
 #include "D3DPostProcess.h"
 #include <IFlashUI.h>
 
 
 
 
 
 
 #undef min
 #undef max
 
 //===============================================================================
 
 RenderTargetData::~RenderTargetData()
 {
 #if defined(DIRECT3D10)
  #if !defined(PS3)
 	CDeviceTexture * pTexMSAA = (CDeviceTexture*)m_pDeviceTextureMSAA;
 	SAFE_RELEASE( pTexMSAA );
 
 	ID3D11ShaderResourceView* pSRVMS = (ID3D11ShaderResourceView*)m_pDeviceShaderResourceMS;
 	SAFE_RELEASE( pSRVMS );
 #endif
 	ID3D11DepthStencilView* pDSV = (ID3D11DepthStencilView*)m_pDeviceDepthStencilSurf;
 	SAFE_RELEASE( pDSV );
 	for( int i = 0; i < 6; ++i )
 	{
 		pDSV = (ID3D11DepthStencilView*)m_pDeviceDepthStencilCMSurfs[i];
 		SAFE_RELEASE( pDSV );
 	}
 
  #if !defined(PS3)
 	for( int i = 0; i < 4; ++i )
 	{
 		ID3D11ShaderResourceView* pSRV = (ID3D11ShaderResourceView*)m_pShaderResourceViews[i];
 		SAFE_RELEASE( pSRV );
 	}
  #endif
 #endif
 }
 //===============================================================================
 
 byte *CTexture::Convert(byte *pSrc, int nWidth, int nHeight, int nMips, ETEX_Format eTFSrc, ETEX_Format eTFDst, int nOutMips, int& nOutSize, bool bLinear)
 {
 	nOutSize = 0;
 	byte *pDst = NULL;
 	if (eTFSrc == eTFDst && nMips == nOutMips)
 		return pSrc;
 	CD3D9Renderer *r = gcpRendD3D;
 #if defined (DIRECT3D9)
 	D3DFormat DeviceFormatSRC = DeviceFormatFromTexFormat(eTFSrc);
 	D3DFormat DeviceFormatDST = DeviceFormatFromTexFormat(eTFDst);
 	if (DeviceFormatSRC == D3DFMT_UNKNOWN || DeviceFormatDST == D3DFMT_UNKNOWN)
 #elif defined (DIRECT3D10)
 	DXGI_FORMAT DeviceFormatSRC = (DXGI_FORMAT)DeviceFormatFromTexFormat(eTFSrc);
 	if (eTFDst == eTF_L8)
 		eTFDst = eTF_A8;
 	DXGI_FORMAT DeviceFormatDST = (DXGI_FORMAT)DeviceFormatFromTexFormat(eTFDst);
 	if (DeviceFormatSRC == DXGI_FORMAT_UNKNOWN || DeviceFormatDST == DXGI_FORMAT_UNKNOWN)
 #endif
 	{
 		assert(0);
 		return NULL;
 	}
 	if (nMips <= 0)
 		nMips = 1;
 	int nSizeDSTMips = 0;
 	int i;
 
 	if (eTFSrc == eTF_3DC)
 	{
 		if(eTFDst == eTF_DXT5)
 		{
 			// convert 3Dc to DXT5 - for compressed normals
 			if (!nOutMips)
 				nOutMips = nMips;
 			int wdt = nWidth;
 			int hgt = nHeight;
 			nSizeDSTMips = CTexture::TextureDataSize(wdt, hgt, 1, nOutMips, eTF_DXT5);
 			pDst = new byte [nSizeDSTMips];
 			int nOffsDST = 0;
 			int nOffsSRC = 0;
 			for (i=0; i<nOutMips; i++)
 			{
 				if (i >= nMips)
 					break;
 				if (wdt <= 0)
 					wdt = 1;
 				if (hgt <= 0)
 					hgt = 1;
 				void *outSrc = &pSrc[nOffsSRC];
 				DWORD outSize = CTexture::TextureDataSize(wdt, hgt, 1, 1, eTFDst);
 
 				nOffsSRC += CTexture::TextureDataSize(wdt, hgt, 1, 1, eTFSrc);
 
 				{
 					byte *src = (byte *)outSrc;
 
 					for (uint32 n=0; n < outSize/16; n++)			// for each block
 					{
 						uint8 *pSrcBlock = &src[n*16];
 						uint8 *pDstBlock = &pDst[nOffsDST+n*16];
 
 						ConvertBlock3DcToDXT5(pDstBlock,pSrcBlock);
 					}
 
 					nOffsDST += outSize;
 				}
 
 				wdt >>= 1;
 				hgt >>= 1;
 			}
 			if ((nOutMips>1 && nOutMips != nMips))
 			{
 				assert(0);			// generate mips if needed - should not happen
 				return 0;
 			}
 			nOutSize = nSizeDSTMips;
 			return pDst;
 		}
 		else
 		{
       assert(0);
 			return NULL;
 		}
 	}
 	else
 	if (DDSFormats::IsNormalMap(eTFDst))
 	{
     assert(0);
 		return NULL;
 	}
 	else
 	{
 
 
 
 
 
 
 
 #if defined (DIRECT3D9)
 		D3DTexture *pID3DTextureDST = NULL;
 		D3DSurface *pSurfDST;
 		D3DLOCKED_RECT d3dlr;
 		HRESULT h;
 		if(FAILED(h = D3DXCreateTexture(gcpRendD3D->GetDevice(), nWidth, nHeight, nOutMips, 0, DeviceFormatDST, D3DPOOL_SYSTEMMEM, &pID3DTextureDST)))
 			return NULL;
 		int wdt = nWidth;
 		int hgt = nHeight;
 		int nOffsSRC = 0;
 		for (i=0; i<nMips; i++)
 		{
 			if (!wdt)
 				wdt = 1;
 			if (!hgt)
 				hgt = 1;
 			int nSizeSRC = TextureDataSize(wdt, hgt, 1, 1, eTFSrc);
 			h = pID3DTextureDST->GetSurfaceLevel(i, &pSurfDST);
 
 			int nPitch;
 			if (!IsDXTCompressed(eTFSrc))
 				nPitch = nSizeSRC / hgt;
 			else
 			{
 				int blockSize = (eTFSrc == eTF_DXT1 || eTFSrc == eTF_CTX1) ? 8 : 16;
 				nPitch = (wdt+3)/4 * blockSize;
 			}
 			RECT srcRect;
 			srcRect.left = 0;
 			srcRect.top = 0;
 			srcRect.right = wdt;
 			srcRect.bottom = hgt;
 
 			h = D3DXLoadSurfaceFromMemory(pSurfDST, NULL, NULL, &pSrc[nOffsSRC], DeviceFormatSRC, nPitch, NULL, &srcRect, D3DX_FILTER_NONE, 0);
 
 			SAFE_RELEASE(pSurfDST);
 
 			nOffsSRC += nSizeSRC;
 			wdt >>= 1;
 			hgt >>= 1;
 		}
 		if (nMips <= 1 && nOutMips > 1)
 			h = D3DXFilterTexture(pID3DTextureDST, NULL, D3DX_DEFAULT, D3DX_FILTER_LINEAR);
 		wdt = nWidth;
 		hgt = nHeight;
 		nSizeDSTMips = TextureDataSize(wdt, hgt, 1, nOutMips, eTFDst);
 		pDst = new byte[nSizeDSTMips];
 		int nOffsDST = 0;
 		for (i=0; i<nOutMips; i++)
 		{
 			if (!wdt)
 				wdt = 1;
 			if (!hgt)
 				hgt = 1;
 			int nSizeDST = TextureDataSize(wdt, hgt, 1, 1, eTFDst);
 
 			pID3DTextureDST->LockRect(i, &d3dlr, NULL, 0);
 			memcpy(&pDst[nOffsDST], d3dlr.pBits, nSizeDST);
 			pID3DTextureDST->UnlockRect(i);
 
 			nOffsDST += nSizeDST;
 			wdt >>= 1;
 			hgt >>= 1;
 		}
 		SAFE_RELEASE(pID3DTextureDST);
 #elif defined (DIRECT3D10) && !defined(gringo)
 		if (eTFDst == eTF_A8 && (eTFSrc == eTF_X8R8G8B8 || eTFSrc == eTF_A8R8G8B8) && nMips == nOutMips)
 		{
 			int nSrcSize = CTexture::TextureDataSize(nWidth, nHeight, 1, nMips, eTFSrc) / 4;
 			pDst = new byte[nSrcSize];
 			for (i=0; i<nSrcSize; i++)
 			{
 				pDst[i] = (pSrc[i*4+0] + pSrc[i*4+1] + pSrc[i*4+2]) / 3;
 			}
 			nSizeDSTMips = nSrcSize;
 			return pDst;
 		}
 		D3D11_TEXTURE2D_DESC Desc;
 		ZeroStruct(Desc);
 		D3DTexture *pID3DTextureDST = NULL;
 		Desc.Format = DeviceFormatDST;
 		Desc.Width = nWidth;
 		Desc.Height = nHeight;
 		Desc.MipLevels = nOutMips;
 		Desc.ArraySize = 1;
 		Desc.SampleDesc.Count = 1;
 		Desc.Usage = D3D11_USAGE_STAGING;
 		Desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
 		Desc.BindFlags = 0;
 		gcpRendD3D->m_pd3dDevice->CreateTexture2D(&Desc, NULL, &pID3DTextureDST);
 		int nSrcSize = CTexture::TextureDataSize(nWidth, nHeight, 1, nMips, eTFSrc);
 		D3DX11_IMAGE_LOAD_INFO LoadInfo;
 		ZeroStruct(LoadInfo);
 		LoadInfo.Width = D3DX_FROM_FILE;
 		LoadInfo.Height = D3DX_FROM_FILE;
 		LoadInfo.Depth = D3DX_FROM_FILE;
 		LoadInfo.FirstMipLevel = 0;
 		LoadInfo.MipLevels = nOutMips;
 		LoadInfo.Usage = D3D11_USAGE_STAGING;
 		LoadInfo.BindFlags = 0;
 		LoadInfo.CpuAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
 		LoadInfo.MiscFlags = 0;
 		LoadInfo.Format = DeviceFormatDST;
 		LoadInfo.Filter = D3DX11_FILTER_NONE;
 		LoadInfo.MipFilter = D3DX11_FILTER_NONE;
 
 		D3DX11_IMAGE_INFO ImgInfo;
 		ZeroStruct(ImgInfo);
 		ImgInfo.Width = nWidth;
 		ImgInfo.Height = nHeight;
 		ImgInfo.Depth = 1;
 		ImgInfo.Format = DeviceFormatSRC;
 		ImgInfo.MipLevels = nMips;
 		ImgInfo.ArraySize = 1;
 		ImgInfo.ImageFileFormat = D3DX11_IFF_DDS;
 		ImgInfo.ResourceDimension = D3D11_RESOURCE_DIMENSION_TEXTURE2D;
 
 		LoadInfo.pSrcInfo = &ImgInfo;
 
 		nSizeDSTMips = 0;
 		int nSizeDDS = 0;
 		pDst = WriteDDS(pSrc, nWidth, nHeight, 1, NULL, eTFSrc, nMips, eTT_2D, true, &nSizeDDS);		
 		HRESULT h;
 		h = D3DX11CreateTextureFromMemory(gcpRendD3D->m_pd3dDevice, pDst, nSizeDDS, &LoadInfo, NULL, alias_cast<ID3D11Resource**>(&pID3DTextureDST), &h);
 		assert(SUCCEEDED(h));
 		SAFE_DELETE_ARRAY(pDst);
 		int nDstSize = CTexture::TextureDataSize(nWidth, nHeight, 1, nMips, eTFDst);
 		pDst = new byte[nDstSize];
 		if (pID3DTextureDST)
 		{
 			int nOffsDST = 0;
 			for (i=0; i<nOutMips; i++)
 			{
 				if (!nWidth)
 					nWidth = 1;
 				if (!nHeight)
 					nHeight = 1;
 				int nSizeDST = TextureDataSize(nWidth, nHeight, 1, 1, eTFDst);
 
 				D3D11_MAPPED_SUBRESOURCE MappedTex2D;
 				STALL_PROFILER("set texture");
 				h = gcpRendD3D->m_pd3dDeviceContext->Map(pID3DTextureDST, i, D3D11_MAP_READ, 0, &MappedTex2D);
 				assert(SUCCEEDED(h));
 				memcpy(&pDst[nOffsDST], MappedTex2D.pData, nSizeDST);
 				gcpRendD3D->m_pd3dDeviceContext->Unmap(pID3DTextureDST, i);
 
 				nOffsDST += nSizeDST;
 				nSizeDSTMips += nSizeDST;
 				nWidth >>= 1;
 				nHeight >>= 1;
 			}
 			SAFE_RELEASE(pID3DTextureDST);
 		}
 #endif
 	}
 	nOutSize = nSizeDSTMips;
 	return pDst;
 }
 
 D3DSurface *CTexture::GetSurface(int nCMSide, int nLevel)
 {
 	if (!m_pDevTexture)
 		return NULL;
 
 	SCOPED_RENDERER_ALLOCATION_NAME_HINT( GetSourceName() );
 
 	HRESULT hr = S_OK;
 #if defined (DIRECT3D9)
 	LPDIRECT3DSURFACE9 pTargSurf = NULL;
 	if (m_eTT == eTT_Cube || m_eTT == eTT_AutoCube)
 	{
 		assert(nCMSide >= 0 && nCMSide < 6);
 		D3DCubeTexture *pID3DTargetCubeTexture = m_pDevTexture->GetCubeTexture();
 		if ((uint32)nLevel >= pID3DTargetCubeTexture->GetLevelCount())
 			return NULL;
 		hr = pID3DTargetCubeTexture->GetCubeMapSurface((D3DCUBEMAP_FACES)nCMSide, nLevel, &pTargSurf);
 	}
 	else
   if (m_eTT == eTT_2D || m_eTT == eTT_Auto2D)
 	{
 		D3DTexture *pID3DTargetTexture = m_pDevTexture->Get2DTexture();
 		if ((uint32)nLevel >= pID3DTargetTexture->GetLevelCount())
 			return NULL;
 		hr = pID3DTargetTexture->GetSurfaceLevel(nLevel, &pTargSurf);
 	}
 #elif defined (DIRECT3D10)
 	ID3D11Texture2D *pID3DTexture = NULL;
 	ID3D11Texture3D *pID3DTexture3D = NULL;
 	ID3D11Texture2D *pID3DTextureCube = NULL;
 	ID3D11RenderTargetView *pTargSurf = (ID3D11RenderTargetView *)m_pDeviceRTV;
   const bool bUseMultisampledRTV = ((m_nFlags & FT_USAGE_MSAA) && m_bUseMultisampledRTV) != 0;
 #if !defined(PS3)
   if (bUseMultisampledRTV)
     pTargSurf = (ID3D11RenderTargetView *)m_pDeviceRTVMS;
 #endif
 
 	if (!pTargSurf)
 	{
 		if (m_eTT == eTT_2D)
 		{
 			pID3DTexture = m_pDevTexture->Get2DTexture();
 #if !defined(PS3)
 			if (bUseMultisampledRTV)
 				pID3DTexture = (ID3D11Texture2D *)m_pRenderTargetData->m_pDeviceTextureMSAA->Get2DTexture();
 #endif
 			D3D11_RENDER_TARGET_VIEW_DESC DescRT;
 			ZeroStruct(DescRT);
 			DescRT.Format = (DXGI_FORMAT)m_pPixelFormat->DeviceFormat;
 			DescRT.ViewDimension = (bUseMultisampledRTV) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D;
 
 
 
 
 			hr = gcpRendD3D->m_pd3dDevice->CreateRenderTargetView(pID3DTexture, &DescRT, &pTargSurf);
 		}
 		else
 		if (m_eTT == eTT_Cube)
 		{
 			pID3DTextureCube = m_pDevTexture->GetCubeTexture();
 
 			D3D11_RENDER_TARGET_VIEW_DESC DescRT;
 			ZeroStruct(DescRT);
 			DescRT.Format = (DXGI_FORMAT)m_pPixelFormat->DeviceFormat;
 			DescRT.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
 			DescRT.Texture2DArray.FirstArraySlice = nCMSide;
 			DescRT.Texture2DArray.ArraySize = 1;
 			DescRT.Texture2DArray.MipSlice = 0;
 			hr = gcpRendD3D->m_pd3dDevice->CreateRenderTargetView(pID3DTextureCube, &DescRT, &pTargSurf);
 		}
 
 #if !defined(PS3)
     if (bUseMultisampledRTV)
   		m_pDeviceRTVMS = pTargSurf;
     else
 #endif
       m_pDeviceRTV = pTargSurf;
 
 	}
 #endif
 	assert(hr == S_OK);
 
 	if(FAILED(hr))
 		pTargSurf = NULL;
 
 	return pTargSurf;
 }
 
 
 
 void CTexture::hintRelease() { if( m_pDevTexture ) m_pDevTexture->free(); }
 
 
 D3DPOOL CTexture::GetPool()
 {
   if (!m_pDevTexture)
     return D3DPOOL_SYSTEMMEM;
   HRESULT hr = S_OK;
   D3DPOOL Pool = D3DPOOL_SYSTEMMEM;
   int nLevel = 0;
 #if defined (DIRECT3D9)
   if (m_eTT == eTT_Cube || m_eTT == eTT_AutoCube)
   {
     D3DSURFACE_DESC Desc;
     D3DCubeTexture *pID3DTexture = m_pDevTexture->GetCubeTexture();
     hr = pID3DTexture->GetLevelDesc(nLevel, &Desc);
     Pool = Desc.Pool;
   }
   else
   if (m_eTT == eTT_2D || m_eTT == eTT_Auto2D)
   {
     D3DSURFACE_DESC Desc;
     D3DTexture *pID3DTexture = m_pDevTexture->Get2DTexture();
     hr = pID3DTexture->GetLevelDesc(nLevel, &Desc);
     Pool = Desc.Pool;
   }
   else
   if (m_eTT == eTT_3D)
   {
     D3DVOLUME_DESC Desc;
     D3DVolumeTexture *pID3DTexture = m_pDevTexture->GetVolumeTexture();
     hr = pID3DTexture->GetLevelDesc(nLevel, &Desc);
     Pool = Desc.Pool;
   }
 #elif defined (DIRECT3D10)
   Pool = D3DPOOL_MANAGED;
   if (m_eTT == eTT_2D || m_eTT == eTT_Auto2D)
   {
     D3D11_TEXTURE2D_DESC Desc;
     D3DTexture *pID3DTexture = m_pDevTexture->Get2DTexture();
     pID3DTexture->GetDesc(&Desc);
     if (Desc.BindFlags & D3D11_BIND_RENDER_TARGET)
       Pool = D3DPOOL_DEFAULT;
   }
   else
   if (m_eTT == eTT_Cube || m_eTT == eTT_AutoCube)
   {
     D3D11_TEXTURE2D_DESC Desc;
     D3DCubeTexture *pID3DTexture = m_pDevTexture->GetCubeTexture();
     pID3DTexture->GetDesc(&Desc);
     if (Desc.BindFlags & D3D11_BIND_RENDER_TARGET)
       Pool = D3DPOOL_DEFAULT;
   }
   else
   if (m_eTT == eTT_3D)
   {
     D3D11_TEXTURE3D_DESC Desc;
     D3DVolumeTexture *pID3DTexture = m_pDevTexture->GetVolumeTexture();
     pID3DTexture->GetDesc(&Desc);
     if (Desc.BindFlags & D3D11_BIND_RENDER_TARGET)
       Pool = D3DPOOL_DEFAULT;
   }
 #endif
   assert(hr == S_OK);
 
   return Pool;
 }
 
 // this function is valid for FT_USAGE_DEPTHSTENCIL textures only
 D3DFormat CTexture::DeviceFormatFromTexFormat(ETEX_Format eTF)
 {
 #if defined (DIRECT3D9)
 	switch (eTF)
 	{
 	case eTF_A8R8G8B8:
 		return D3DFMT_A8R8G8B8;
 	case eTF_X8R8G8B8:
 		return D3DFMT_X8R8G8B8;
 	case eTF_A8:
 		return D3DFMT_A8;
 
 
 
 
 
 
 
 
 
 
 	case eTF_A8L8:
 		return D3DFMT_A8L8;
 	case eTF_L8:
 		return D3DFMT_L8;
 	case eTF_A4R4G4B4:
 		return D3DFMT_A4R4G4B4;
 	case eTF_R5G6B5:
 		return D3DFMT_R5G6B5;
 	case eTF_R5G5B5:
 		return D3DFMT_X1R5G5B5;
 	case eTF_V8U8:
 		return D3DFMT_V8U8;
 #if !defined(XENON)
 	case eTF_R8G8B8:
 		return D3DFMT_R8G8B8;
 	case eTF_CxV8U8:
 		return D3DFMT_CxV8U8;
 #endif
 	case eTF_X8L8V8U8:
 		return D3DFMT_X8L8V8U8;
 	case eTF_L8V8U8:
 		assert(0);
 		break;
 	case eTF_V16U16:
 		return D3DFMT_V16U16;
 	case eTF_A16B16G16R16:
 		return D3DFMT_A16B16G16R16;
 	case eTF_A16B16G16R16F:
 		return D3DFMT_A16B16G16R16F;
 	case eTF_A32B32G32R32F:
 		return D3DFMT_A32B32G32R32F;
 	case eTF_R32F:
 		return D3DFMT_R32F;
 	case eTF_R16F:
 		return D3DFMT_R16F;
 	case eTF_G16R16:
 		return D3DFMT_G16R16;
 	case eTF_G16R16F:
 		return D3DFMT_G16R16F;
 	case eTF_DXT1:
 		return D3DFMT_DXT1;
 	case eTF_DXT3:
 		return D3DFMT_DXT3;
 	case eTF_DXT5:
 		return D3DFMT_DXT5;
 	case eTF_3DC:
 		return D3DFMT_3DC;
 	case eTF_DEPTH16:
 		return D3DFMT_D16;
 	case eTF_DEPTH24:
 #if defined(INVERT_DEPTH_RANGE)
 		return D3DFMT_D24FS8;
 #else
 		return D3DFMT_D24X8;
 #endif
 	case eTF_DF16:
 		return D3DFMT_DF16;
 	case eTF_DF24:
 		return D3DFMT_DF24;
 	case eTF_D16:
 		return D3DFMT_D16;
 	case eTF_D24S8:
 		return D3DFMT_D24S8;
 	case eTF_NULL:
 		return D3DFMT_NULL;
 
 
 	default:
 		assert(0);
 	}
 	return D3DFMT_UNKNOWN;
 #elif defined (DIRECT3D10)
 	switch (eTF)
 	{
 	case eTF_R8G8B8:
 		return DXGI_FORMAT_R8G8B8A8_UNORM;
 	case eTF_A8R8G8B8:
 		return DXGI_FORMAT_R8G8B8A8_UNORM;
 	case eTF_X8R8G8B8:
 		return DXGI_FORMAT_R8G8B8A8_UNORM;
 	case eTF_A8:
 		return DXGI_FORMAT_A8_UNORM;
 	case eTF_A8L8:
 		return DXGI_FORMAT_UNKNOWN;
 	case eTF_L8:
 
 
 
 		return DXGI_FORMAT_UNKNOWN;
 	case eTF_A4R4G4B4:
 		return DXGI_FORMAT_UNKNOWN;
 	case eTF_R5G6B5:
 		return DXGI_FORMAT_B5G6R5_UNORM;
 	case eTF_R5G5B5:
 		return DXGI_FORMAT_B5G5R5A1_UNORM;
 	case eTF_V8U8:
 		return DXGI_FORMAT_R8G8_UNORM;
 	case eTF_X8L8V8U8:
 		return DXGI_FORMAT_R8G8B8A8_UNORM;
 	case eTF_L8V8U8:
 		assert(0);
 		break;
 	case eTF_V16U16:
 		return DXGI_FORMAT_R16G16_UNORM;
 	case eTF_A16B16G16R16:
 		return DXGI_FORMAT_R16G16B16A16_UNORM;
 	case eTF_A16B16G16R16F:
 		return DXGI_FORMAT_R16G16B16A16_FLOAT;
 	case eTF_A32B32G32R32F:
 		return DXGI_FORMAT_R32G32B32A32_FLOAT;
 	case eTF_R32F:
 		return DXGI_FORMAT_R32_FLOAT;
 	case eTF_R16F:
 		return DXGI_FORMAT_R16_FLOAT;
 	case eTF_G16R16F:
 		return DXGI_FORMAT_R16G16_FLOAT;
 	case eTF_DXT1:
 		return DXGI_FORMAT_BC1_UNORM;
 	case eTF_DXT3:
 		return DXGI_FORMAT_BC2_UNORM;
 	case eTF_DXT5:
 		return DXGI_FORMAT_BC3_UNORM;
 	case eTF_3DC:
 		return DXGI_FORMAT_BC5_UNORM;
 	case eTF_DEPTH16:
 		return DXGI_FORMAT_D16_UNORM;
 	case eTF_D24S8:
 		return DXGI_FORMAT_D24_UNORM_S8_UINT;
 	case eTF_D32F:
 		return DXGI_FORMAT_D32_FLOAT;
 
 	default:
 		assert(0);
 	}
 	return DXGI_FORMAT_UNKNOWN;
 #endif
 }
 
 D3DFormat CTexture::GetD3DLinFormat(D3DFormat nFormat)
 {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	return nFormat;
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 D3DFormat CTexture::ConvertToSRGBFmt(D3DFormat fmt)
 {
 #if (defined(DIRECT3D10) || defined(CAFE)) && !defined(PS3)
 	switch (fmt)
 	{
 	case DXGI_FORMAT_R8G8B8A8_UNORM:
 		return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
 	case DXGI_FORMAT_BC1_UNORM:
 		return DXGI_FORMAT_BC1_UNORM_SRGB;
 	case DXGI_FORMAT_BC2_UNORM:
 		return DXGI_FORMAT_BC2_UNORM_SRGB;
 	case DXGI_FORMAT_BC3_UNORM:
 		return DXGI_FORMAT_BC3_UNORM_SRGB;
 		// AntonK: we don't need sRGB space for fp formats, because there is enough precision
 	case DXGI_FORMAT_R16G16B16A16_FLOAT:
 		return DXGI_FORMAT_R16G16B16A16_FLOAT;
 	default:
 		assert(0);
 		return fmt;
 	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	#else
	return fmt;
 #endif
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #if defined (DIRECT3D10)
 ETEX_Format CTexture::TexFormatFromDeviceFormat(D3DFormat nFormat)
 {
 	switch (nFormat)
 	{
 		case DXGI_FORMAT_R8G8B8A8_UNORM:
 			return eTF_A8R8G8B8;
 		case DXGI_FORMAT_A8_UNORM:
 			return eTF_A8;
 		case DXGI_FORMAT_B5G6R5_UNORM:
 			return eTF_R5G6B5;
 		case DXGI_FORMAT_B5G5R5A1_UNORM:
 			return eTF_R5G5B5;
 		case DXGI_FORMAT_R8G8_UNORM:
 			return eTF_V8U8;
 		case DXGI_FORMAT_R8G8B8A8_SNORM:
 			return eTF_X8L8V8U8;
 		case DXGI_FORMAT_R16G16_SNORM:
 			return eTF_V16U16;
 		case DXGI_FORMAT_R16G16B16A16_UNORM:
 			return eTF_A16B16G16R16;
 		case DXGI_FORMAT_R16G16B16A16_FLOAT:
 			return eTF_A16B16G16R16F;
 		case DXGI_FORMAT_R32G32B32A32_FLOAT:
 			return eTF_A32B32G32R32F;
 		case DXGI_FORMAT_R32_FLOAT:
 		case DXGI_FORMAT_R32_TYPELESS:
 			return eTF_R32F;
 		case DXGI_FORMAT_R16_TYPELESS:
 		case DXGI_FORMAT_R16_FLOAT:
 			return eTF_R16F;
 		case DXGI_FORMAT_R16G16_FLOAT:
 			return eTF_G16R16F;
 		case DXGI_FORMAT_BC1_UNORM:
 			return eTF_DXT1;
 		case DXGI_FORMAT_BC2_UNORM:
 			return eTF_DXT3;
 		case DXGI_FORMAT_BC3_UNORM:
 			return eTF_DXT5;
 		case DXGI_FORMAT_BC5_UNORM:
 			return eTF_3DC;
 		case DXGI_FORMAT_D16_UNORM:
 			return eTF_DEPTH16;
 		case DXGI_FORMAT_R24G8_TYPELESS:
 		case DXGI_FORMAT_D24_UNORM_S8_UINT:
 			return eTF_D24S8;
 		case DXGI_FORMAT_D32_FLOAT:
 			return eTF_D32F;
 	default:
 
 
 
 		assert(0);
 
 	}
 	return eTF_Unknown;
 }
 
 // this function is valid for FT_USAGE_DEPTHSTENCIL textures only
 D3DFormat CTexture::ConvertToDepthStencilFmt( D3DFormat nFormat )
 {
 	switch (nFormat)
 	{
 	case (DXGI_FORMAT_R24G8_TYPELESS):    return DXGI_FORMAT_D24_UNORM_S8_UINT;
 	case (DXGI_FORMAT_R32G8X24_TYPELESS): return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
 		//case (DXGI_FORMAT_R32G32_TYPELESS):   return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
 	case (DXGI_FORMAT_R32_TYPELESS):      return DXGI_FORMAT_D32_FLOAT;
 	case (DXGI_FORMAT_R16_TYPELESS):      return DXGI_FORMAT_D16_UNORM;
 	default: break;
 	}
 	assert( 0 );
 	return DXGI_FORMAT_UNKNOWN;
 }
 
 D3DFormat CTexture::ConvertToShaderResourceFmt(D3DFormat nFormat)
 {
 	//handle special cases
 	switch (nFormat)
 	{
 	case (DXGI_FORMAT_R24G8_TYPELESS):    return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
 	case (DXGI_FORMAT_R32G8X24_TYPELESS): return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
 		//case (DXGI_FORMAT_R32G32_TYPELESS):   return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
 	case (DXGI_FORMAT_R32_TYPELESS):      return DXGI_FORMAT_R32_FLOAT;
 	case (DXGI_FORMAT_R16_TYPELESS):      return DXGI_FORMAT_R16_UNORM;
 
 		/*
 		//128 bits
 		DXGI_FORMAT_R32G32B32A32_TYPELESS,
 		DXGI_FORMAT_R32G32B32_TYPELESS,
 
 		//64 bits
 		DXGI_FORMAT_R16G16B16A16_TYPELESS,
 		DXGI_FORMAT_R32G32_TYPELESS,
 		DXGI_FORMAT_R32G8X24_TYPELESS,
 		DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS,
 		DXGI_FORMAT_X32_TYPELESS_G8X24_UINT,
 
 		//32 bits
 		DXGI_FORMAT_R10G10B10A2_TYPELESS,
 		DXGI_FORMAT_R8G8B8A8_TYPELESS,
 		DXGI_FORMAT_R16G16_TYPELESS,
 		DXGI_FORMAT_R32_TYPELESS,
 		DXGI_FORMAT_R24G8_TYPELESS,
 		DXGI_FORMAT_R24_UNORM_X8_TYPELESS,
 		DXGI_FORMAT_X24_TYPELESS_G8_UINT,
 
 		//16 bits
 		DXGI_FORMAT_R8G8_TYPELESS,
 		DXGI_FORMAT_R16_TYPELESS,
 
 		//8 bits
 		DXGI_FORMAT_R8_TYPELESS,
 
 		//block formats
 		DXGI_FORMAT_BC1_TYPELESS,
 		DXGI_FORMAT_BC2_TYPELESS,
 		DXGI_FORMAT_BC3_TYPELESS,
 		DXGI_FORMAT_BC4_TYPELESS,
 		DXGI_FORMAT_BC5_TYPELESS,
 		*/
 
 	default: break;
 	}
 
 	//pass through
 	return nFormat;
 }
 
 
 
 D3DFormat CTexture::ConvertToTypelessFmt(D3DFormat fmt)
 {
   switch (fmt)
   {
     case DXGI_FORMAT_R32G32B32A32_FLOAT:
     case DXGI_FORMAT_R32G32B32A32_UINT:
     case DXGI_FORMAT_R32G32B32A32_SINT:
       return DXGI_FORMAT_R32G32B32A32_TYPELESS; break;
 
     case DXGI_FORMAT_R32G32B32_FLOAT:
     case DXGI_FORMAT_R32G32B32_UINT:
     case DXGI_FORMAT_R32G32B32_SINT:
       return DXGI_FORMAT_R32G32B32_TYPELESS; break;
 
     case DXGI_FORMAT_R16G16B16A16_FLOAT:
     case DXGI_FORMAT_R16G16B16A16_UNORM:
     case DXGI_FORMAT_R16G16B16A16_UINT:
     case DXGI_FORMAT_R16G16B16A16_SNORM:
     case DXGI_FORMAT_R16G16B16A16_SINT:
       return DXGI_FORMAT_R16G16B16A16_TYPELESS; break;
 
     case DXGI_FORMAT_R32G32_FLOAT:
     case DXGI_FORMAT_R32G32_UINT:
     case DXGI_FORMAT_R32G32_SINT:
       return DXGI_FORMAT_R32G32_TYPELESS; break;
 
     case DXGI_FORMAT_R10G10B10A2_UNORM:
     case DXGI_FORMAT_R10G10B10A2_UINT:
       return DXGI_FORMAT_R10G10B10A2_TYPELESS; break;
 
     case DXGI_FORMAT_R8G8B8A8_UNORM:
     case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
     case DXGI_FORMAT_R8G8B8A8_UINT:
     case DXGI_FORMAT_R8G8B8A8_SNORM:
     case DXGI_FORMAT_R8G8B8A8_SINT:
       return DXGI_FORMAT_R8G8B8A8_TYPELESS; break;
 
     case DXGI_FORMAT_BC1_UNORM:
     case DXGI_FORMAT_BC1_UNORM_SRGB:
       return DXGI_FORMAT_BC1_TYPELESS; break;
 
     case DXGI_FORMAT_BC2_UNORM:
     case DXGI_FORMAT_BC2_UNORM_SRGB:
       return DXGI_FORMAT_BC2_TYPELESS; break;
 
     case DXGI_FORMAT_BC3_UNORM:
     case DXGI_FORMAT_BC3_UNORM_SRGB:
       return DXGI_FORMAT_BC3_TYPELESS; break;
 
       // todo: add missing formats if they found required
 
   default:
     assert(0);
     return fmt;
   }
 }
 
 #else
 ETEX_Format CTexture::TexFormatFromDeviceFormat(D3DFormat nFormat)
 {
 	switch (nFormat)
 	{
 #if !defined(XENON)
 		case D3DFMT_R8G8B8:
 			return eTF_R8G8B8;
 #endif
 		case D3DFMT_A8R8G8B8:
 			return eTF_A8R8G8B8;
 		case D3DFMT_X8R8G8B8:
 			return eTF_X8R8G8B8;
 		case D3DFMT_A8:
 			return eTF_A8;
 
 
 
 
 
 
 
 
 
 
 
 
 
 		case D3DFMT_A8L8:
 			return eTF_A8L8;
 		case D3DFMT_L8:
 			return eTF_L8;
 		case D3DFMT_A4R4G4B4:
 			return eTF_A4R4G4B4;
 		case D3DFMT_R5G6B5:
 			return eTF_R5G6B5;
 		case D3DFMT_X1R5G5B5:
 			return eTF_R5G5B5;
 		case D3DFMT_V8U8:
 			return eTF_V8U8;
 #if !defined(XENON)
 		case D3DFMT_CxV8U8:
 			return eTF_CxV8U8;
 #endif
 		case D3DFMT_X8L8V8U8:
 			return eTF_X8L8V8U8;
 		case D3DFMT_V16U16:
 			return eTF_V16U16;
 		case D3DFMT_A16B16G16R16:
 			return eTF_A16B16G16R16;
 		case D3DFMT_A16B16G16R16F:
 			return eTF_A16B16G16R16F;
 		case D3DFMT_A32B32G32R32F:
 			return eTF_A32B32G32R32F;
 		case D3DFMT_R32F:
 			return eTF_R32F;
 		case D3DFMT_R16F:
 			return eTF_R16F;
 		case D3DFMT_G16R16:
 			return eTF_G16R16;
 		case D3DFMT_G16R16F:
 			return eTF_G16R16F;
 		case D3DFMT_DXT1:
 			return eTF_DXT1;
 		case D3DFMT_DXT3:
 			return eTF_DXT3;
 		case D3DFMT_DXT5:
 			return eTF_DXT5;
 #if !defined(PS3)
 		case D3DFMT_3DC:
 			return eTF_3DC;
 #endif
 		case D3DFMT_D24X8:
 			return eTF_DEPTH24;
 		case D3DFMT_DF16:
 			return eTF_DF16;
 		case D3DFMT_DF24:
 			return eTF_DF24;
 		case D3DFMT_D16:
 			return eTF_D16;
 		case D3DFMT_D24S8:
 			return eTF_D24S8;
 		case D3DFMT_NULL:
 			return eTF_NULL;
 
 			// sRGB formats
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		default:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			break;
 	}
 	assert(0);
 	return eTF_Unknown;
 }
 
 D3DFormat CTexture::ConvertToDepthStencilFmt( D3DFormat nFormat )
 {
 	assert(0);
 	return (D3DFormat)0;
 }
 
 D3DFormat CTexture::ConvertToShaderResourceFmt(D3DFormat nFormat)
 {
 	assert(0);
 	return (D3DFormat)0;
 }
 
 #endif
 bool CTexture::IsFormatSupported(ETEX_Format eTFDst)
 {
 	CD3D9Renderer *rd = gcpRendD3D;
 	int D3DFmt = DeviceFormatFromTexFormat(eTFDst);
 	if (!D3DFmt)
 		return false;
 	SPixFormat *pFmt;
 	for (pFmt=rd->m_FirstPixelFormat; pFmt; pFmt=pFmt->Next)
 	{
 		if (pFmt->DeviceFormat == D3DFmt && pFmt->IsValid())
 			return true;
 	}
 	return false;
 }
 
 ETEX_Format CTexture::ClosestFormatSupported(ETEX_Format eTFDst)
 {
 	CD3D9Renderer *rd = gcpRendD3D;
 
 	switch (eTFDst)
 	{
 	case eTF_A8R8G8B8:
 		if (rd->m_FormatA8R8G8B8.BitsPerPixel)
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		if (rd->m_FormatA4R4G4B4.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA4R4G4B4;
 			return eTF_A4R4G4B4;
 		}
 		return eTF_Unknown;
 
 	case eTF_X8R8G8B8:
 		if (rd->m_FormatX8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatX8R8G8B8;
 			return eTF_X8R8G8B8;
 		}
 		if (rd->m_FormatA8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		return eTF_Unknown;
 
 	case eTF_A4R4G4B4:
 		if (rd->m_FormatA4R4G4B4.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA4R4G4B4;
 			return eTF_A4R4G4B4;
 		}
 		if (rd->m_FormatA8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		return eTF_Unknown;
 
 	case eTF_R5G6B5:
 		if (rd->m_FormatR5G6B5.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatR5G6B5;
 			return eTF_R5G6B5;
 		}
 		if (rd->m_FormatX8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatX8R8G8B8;
 			return eTF_X8R8G8B8;
 		}
 		return eTF_Unknown;
 
 	case eTF_A8:
 		if (rd->m_FormatA8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8;
 			return eTF_A8;
 		}
 		if (rd->m_FormatA8L8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8L8;
 			return eTF_A8L8;
 		}
 		return eTF_Unknown;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	case eTF_L8:
 		if (rd->m_FormatL8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatL8;
 			return eTF_L8;
 		}
 		if (rd->m_FormatA8L8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8L8;
 			return eTF_A8L8;
 		}
 		return eTF_Unknown;
 
 	case eTF_A8L8:
 		if (rd->m_FormatA8L8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8L8;
 			return eTF_A8L8;
 		}
 		return eTF_Unknown;
 
 	case eTF_DXT1:
 		if (rd->m_FormatDXT1.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDXT1;
 			return eTF_DXT1;
 		}
 		if (rd->m_FormatX8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatX8R8G8B8;
 			return eTF_X8R8G8B8;
 		}
 		if (rd->m_FormatA8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		return eTF_Unknown;
 
 	case eTF_DXT3:
 		if (rd->m_FormatDXT3.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDXT3;
 			return eTF_DXT3;
 		}
 		if (rd->m_FormatA8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		if (rd->m_FormatA4R4G4B4.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA4R4G4B4;
 			return eTF_A4R4G4B4;
 		}
 		return eTF_Unknown;
 
 	case eTF_DXT5:
 		if (rd->m_FormatDXT5.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDXT5;
 			return eTF_DXT5;
 		}
 		if (rd->m_FormatA8R8G8B8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA8R8G8B8;
 			return eTF_A8R8G8B8;
 		}
 		if (rd->m_FormatA4R4G4B4.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA4R4G4B4;
 			return eTF_A4R4G4B4;
 		}
 		return eTF_Unknown;
 
 	case eTF_3DC:
 		if (rd->m_Format3Dc.IsValid())
 		{
 			m_pPixelFormat = &rd->m_Format3Dc;
 			return eTF_3DC;
 		}
 		return eTF_Unknown;
 
 	case eTF_A16B16G16R16F:
 		if (rd->m_FormatA16B16G16R16F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA16B16G16R16F;
 			return eTF_A16B16G16R16F;
 		}
 		return eTF_Unknown;
 
   case eTF_A16B16G16R16:
     if (rd->m_FormatA16B16G16R16.IsValid())
     {
       m_pPixelFormat = &rd->m_FormatA16B16G16R16;
       return eTF_A16B16G16R16;
     }
     return eTF_Unknown;
 
   case eTF_A2R10G10B10:
     if (rd->m_FormatA2R10G10B10.IsValid())
     {
       m_pPixelFormat = &rd->m_FormatA2R10G10B10;
       return eTF_A2R10G10B10;
     }
     return eTF_Unknown;
 
 	case eTF_G16R16:
 		if (rd->m_FormatG16R16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatG16R16;
 			return eTF_G16R16;
 		}
 		return eTF_Unknown;
 
 	case eTF_G16R16F:
 		if (rd->m_FormatG16R16F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatG16R16F;
 			return eTF_G16R16F;
 		}
 		return eTF_Unknown;
 
 	case eTF_V16U16:
 		if (rd->m_FormatV16U16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatV16U16;
 			return eTF_V16U16;
 		}
 		return eTF_Unknown;
 
 	case eTF_A32B32G32R32F:
 		if (rd->m_FormatA32B32G32R32F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatA32B32G32R32F;
 			return eTF_A32B32G32R32F;
 		}
 		return eTF_Unknown;
 
 	case eTF_R32F:
 		if (rd->m_FormatR32F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatR32F;
 			return eTF_R32F;
 		}
 		if (rd->m_FormatG16R16F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatG16R16F;
 			return eTF_G16R16F;
 		}
 		return eTF_Unknown;
 
 	case eTF_R16F:
 		if (rd->m_FormatR16F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatR16F;
 			return eTF_R16F;
 		}
 		if (rd->m_FormatG16R16F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatG16R16F;
 			return eTF_G16R16F;
 		}
 		return eTF_Unknown;
 
 	case eTF_DEPTH24:
 		if (rd->m_FormatDepth24.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDepth24;
 			return eTF_DEPTH24;
 		}
 		if (rd->m_FormatDepth16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDepth16;
 			return eTF_DEPTH16;
 		}
 		return eTF_Unknown;
 
 	case eTF_DEPTH16:
 		if (rd->m_FormatDepth16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDepth16;
 			return eTF_DEPTH16;
 		}
 		if (rd->m_FormatDepth24.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDepth24;
 			return eTF_DEPTH24;
 		}
 		return eTF_Unknown;
 
 	case eTF_DF16:
 		if (rd->m_FormatDF16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDF16;
 			return eTF_DF16;
 		}
 		return eTF_Unknown;
 	case eTF_DF24:
 		if (rd->m_FormatDF24.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatDF24;
 			return eTF_DF24;
 		}
 	case eTF_D16:
 		if (rd->m_FormatD16.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatD16;
 			return eTF_D16;
 		}
 	case eTF_D24S8:
 		if (rd->m_FormatD24S8.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatD24S8;
 			return eTF_D24S8;
 		}
 	case eTF_D32F:
 		if (rd->m_FormatD32F.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatD32F;
 			return eTF_D32F;
 		}
 	case eTF_NULL:
 		if (rd->m_FormatNULL.IsValid())
 		{
 			m_pPixelFormat = &rd->m_FormatNULL;
 			return eTF_NULL;
 		}
 		return eTF_Unknown;
 
 	default:
 		assert(0);
 	}
 	return eTF_Unknown;
 }
 
 bool CTexture::CreateRenderTarget(ETEX_Format eTF)
 {
 	if (eTF == eTF_Unknown)
 		eTF = m_eTFDst;
 	if (eTF == eTF_Unknown)
 		return false;
 	byte *pData[6] = { NULL }; 
 
 	ETEX_Format eTFDst = ClosestFormatSupported(eTF);
 	if (eTF != eTFDst)
 		return false;
 	m_eTFDst = eTF;
 	m_nFlags |= FT_USAGE_RENDERTARGET;
 	bool bRes = CreateDeviceTexture(pData);  
 	PostCreate();
 
 	// Assign name to RT for enhanced debugging
 #ifndef _RELEASE
 	if( bRes )
 	{
 	#if defined( DIRECT3D9 ) && !defined( XENON )
 		m_pDevTexture->GetBaseTexture()->SetPrivateData( WKPDID_D3DDebugObjectName, m_SrcName.c_str(), strlen( m_SrcName.c_str() ), 0 );
 		D3DSurface *surf = GetSurface( -1, 0 );
 		if( surf )
     {
 			surf->SetPrivateData( WKPDID_D3DDebugObjectName, m_SrcName.c_str(), strlen( m_SrcName.c_str() ), 0 );
       surf->Release();
     }
 	#elif defined( DIRECT3D10 ) && !defined( PS3 ) && !defined(CAFE)
 		// Not yet tested
 		m_pDevTexture->GetBaseTexture()->SetPrivateData( WKPDID_D3DDebugObjectName, strlen( m_SrcName.c_str() ), m_SrcName.c_str() );
 		D3DSurface *surf = GetSurface( -1, 0 );
 		if( surf )
 			surf->SetPrivateData( WKPDID_D3DDebugObjectName, strlen( m_SrcName.c_str() ), m_SrcName.c_str() );
 	#endif
 	}
 #endif
 
 	return bRes;
 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 // Resolve anti-aliased RT to the texture
 bool CTexture::Resolve(int nTarget, bool bUseViewportSize)
 {
 	if (m_bResolved)
 		return true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	m_bResolved = true;
 #if !defined(XENON)
 	if (!(m_nFlags & FT_USAGE_MSAA))
 		return true;
 #endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #if defined (DIRECT3D9)
 	assert ((m_nFlags & FT_USAGE_RENDERTARGET) && (m_nFlags & FT_USAGE_MSAA) && m_pDeviceRTV && m_pDevTexture);
 	D3DSurface *pDestSurf = GetSurface(-1, 0);
 	D3DSurface *pSrcSurf = (D3DSurface *)m_pDeviceRTV;
 
 	RECT pSrcRect={0, 0, m_nWidth, m_nHeight};
 	RECT pDstRect={0, 0, m_nWidth, m_nHeight};
 
 	gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_RTCopied++;
 	gcpRendD3D->m_RP.m_PS[gcpRendD3D->m_RP.m_nProcessThreadID].m_RTCopiedSize += GetDeviceDataSize();
 	gcpRendD3D->m_pd3dDevice->StretchRect(pSrcSurf, &pSrcRect, pDestSurf, &pDstRect, D3DTEXF_NONE); 
 	SAFE_RELEASE(pDestSurf);
 #elif defined (DIRECT3D10)
 	assert ((m_nFlags & FT_USAGE_RENDERTARGET) && (m_nFlags & FT_USAGE_MSAA) && m_pDeviceShaderResource && m_pDevTexture && m_pRenderTargetData->m_pDeviceTextureMSAA && m_pRenderTargetData->m_pDeviceShaderResourceMS);
 	CDeviceTexture *pDestSurf = GetDevTexture();
 	CDeviceTexture *pSrcSurf =  GetDevTextureMSAA();
 
 	assert(pSrcSurf!=NULL);
 	assert(pDestSurf!=NULL);
 
 	gcpRendD3D->m_pd3dDeviceContext->ResolveSubresource(pDestSurf->Get2DTexture(), 0, pSrcSurf->Get2DTexture(), 0, (DXGI_FORMAT)m_pPixelFormat->DeviceFormat); 
 #endif
 	return true;
 }
 
 
 
 
 bool CTexture::CreateDeviceTexture(byte *pData[6])
 {
 	if (!m_pPixelFormat)
 	{
 		ETEX_Format eTF = ClosestFormatSupported(m_eTFDst);
 
 		//|| defined(PS3)
 #if defined(XENON)  || defined(LINUX)
 		if (eTF == eTF_Unknown)
 			return false;
 #endif
 
 		assert(eTF != eTF_Unknown);
 		assert(eTF == m_eTFDst);
 	}
 	assert(m_pPixelFormat);
 	if (!m_pPixelFormat)
 		return false;
 
 	return gRenDev->m_pRT->RC_CreateDeviceTexture(this, pData);
 }
 
 void CTexture::Unbind()
 {
   for (uint32 i=0; i<MAX_TMU; i++)
   {
     if (s_TexStages[i].m_Texture == this)
     {
       s_TexStages[i].m_Texture = NULL;
 #if defined (DIRECT3D10) 
       ID3D11ShaderResourceView *RV = NULL;
       gcpRendD3D->GetDeviceContext()->PSSetShaderResources(i, 1, &RV);
 #elif defined (DIRECT3D9)
 			int nVtxTexOffSet = (-static_cast<int32>(m_bVertexTexture)) & D3DVERTEXTEXTURESAMPLER0;
       HRESULT hr = gcpRendD3D->GetD3DDevice()->SetTexture(i + nVtxTexOffSet, NULL);
 
 
 
 
 #endif
     }
   }
 }
 bool CTexture::RT_CreateDeviceTexture(byte *pData[6])
 {
 	MEMSTAT_CONTEXT(EMemStatContextTypes::MSC_Texture, 0, "Creating Texture" );
 	MEMSTAT_CONTEXT_FMT(EMemStatContextTypes::MSC_Texture, 0, "%s %ix%ix%i %08x", m_SrcName.c_str(), m_nWidth, m_nHeight, m_nMips, m_nFlags );
 	SCOPED_RENDERER_ALLOCATION_NAME_HINT( GetSourceName() );
 
 	HRESULT hr;
 
 	//if we have any device owned resources allocated, we must sync with render thread
 	if(m_pDevTexture 
 
 
 
 		)
 	{
 		ReleaseDeviceTexture(false);
 	}
 	else
 	{
 		SAFE_DELETE(m_pRenderTargetData);
 	}
 
 	CD3D9Renderer *r = gcpRendD3D;
 	int i;
 	int nWdt = m_nWidth;
 	int nHgt = m_nHeight;
 	int nDepth = m_nDepth;
 	int nMips = m_nMips;
 	assert(nWdt && nHgt && nMips);
 
 	byte *pTemp = NULL;
 
   CDeviceManager *pDevMan = &r->m_DevMan;
 
 	bool resetSRGB = true;
 
 	if(m_nFlags & FT_USAGE_VERTEX_BUFFER)
 	{
 		if(!(gcpRendD3D->GetFeatures() & RFT_HW_R2VB))
 		{
 			assert(0);
 			iLog->Log("Error: CTexture::CreateDeviceTexture: hw doesn't support r2vb, failed to create the texture %s", GetSourceName());
 			return false;
 		}
 		else if(m_eTT != eTT_2D)
 		{
 			assert(0);
 			iLog->Log("Error: CTexture::CreateDeviceTexture: only 2D textures supported for r2vb, failed to create the texture %s", GetSourceName());
 			return false;
 		}
 		else if(m_nMips != 1)
 		{
 			assert(0);
 			iLog->Log("Error: CTexture::CreateDeviceTexture: r2vb doesn't support textures with mips, failed to create the texture %s", GetSourceName());
 			return false;
 		}
 		else if(IsDXTCompressed(m_eTFDst))
 		{
 			assert(0);
 			iLog->Log("Error: CTexture::CreateDeviceTexture: r2vb doesn't support compressed textures, failed to create the texture %s", GetSourceName());
 			return false;
 		}
 	}
 
 	uint32 nUsage = 0;
 
 	if(m_nFlags & FT_USAGE_RENDERTARGET)
 	{
 		assert(m_pRenderTargetData == NULL);
 		m_pRenderTargetData = new RenderTargetData();
 	}
 
 #if defined (DIRECT3D9)
 	int D3DUsage = 0;
 	D3DPOOL D3DPool = TEXPOOL;
 	STexLock lr;
 
 	if (m_nFlags & FT_USAGE_RENDERTARGET)
 	{
 		D3DUsage |= D3DUSAGE_RENDERTARGET;
 		D3DPool = D3DPOOL_DEFAULT;
 	}
 	if (m_nFlags & FT_USAGE_DYNAMIC)
 	{
 		D3DUsage |= D3DUSAGE_DYNAMIC;
 		D3DPool = D3DPOOL_DEFAULT;
 	}
 
 	if( m_nFlags & FT_USAGE_READBACK )
 	{
 		//D3DUsage |= D3DUSAGE_DYNAMIC;
 		D3DPool = D3DPOOL_SYSTEMMEM;
 	}
 
 #if !defined(XENON)
 	// for DX9 ATI R2VB feature
 	if(m_nFlags & FT_USAGE_VERTEX_BUFFER)
 		D3DUsage |= D3DUSAGE_DMAP;
 #endif
 	if (nMips <= 1 && (m_nFlags & (FT_FORCE_MIPS)) )
 	{
 		if (m_pPixelFormat->bCanAutoGenMips)
 		{
 			D3DUsage |= D3DUSAGE_AUTOGENMIPMAP;
 			nMips = 1;
 
 
 
 		}
 		else
 		if (pData[0])
 		{
 			CDeviceTexture *pSrcTexture = NULL;
 			if(FAILED(hr = pDevMan->Create2DTexture(nWdt, nHgt, D3DX_DEFAULT, nUsage, m_pPixelFormat->DeviceFormat, D3DPOOL_SYSTEMMEM, &pSrcTexture, NULL, false, m_nPriority)))
 			{
 				m_nFlags &= ~FT_FORCE_MIPS;
 				nMips = 1;
 				assert(0);
 			}
 			else
 			{
 				int nSize = TextureDataSize(nWdt, nHgt, 1, 1, m_eTFDst);
 				hr = pSrcTexture->LockRect(0, lr, 0);
 				assert(SUCCEEDED(hr));
 				// Copy data to src texture
 				memcpy((byte *)lr.pData, pData[0], nSize);
 				// Unlock the system texture
 				pSrcTexture->UnlockRect(0);
 				hr = D3DXFilterTexture(pSrcTexture->Get2DTexture(), NULL, 0, D3DX_FILTER_LINEAR);
 				assert(SUCCEEDED(hr));
 				nMips = CalcNumMips(nWdt, nHgt);
 				nSize = TextureDataSize(nWdt, nHgt, 1, nMips, m_eTFDst);
 				pTemp = new byte[nSize];
 				int n = pSrcTexture->Get2DTexture()->GetLevelCount();
 				int w = nWdt;
 				int h = nHgt;
 				int nOffs = 0;
 				i = 0;
 				while (w || h)
 				{
 					if (!w)
 						w = 1;
 					if (!h)
 						h = 1;
 					nSize = TextureDataSize(w, h, 1, 1, m_eTFDst);
 					hr = pSrcTexture->LockRect(i, lr, 0);
 					assert(SUCCEEDED(hr));
 					// Copy data to src texture
 					cryMemcpy(&pTemp[nOffs], (byte *)lr.pData, nSize);
 					// Unlock the system texture
 					hr = pSrcTexture->UnlockRect(i);
 					assert(SUCCEEDED(hr));
 					w >>= 1;
 					h >>= 1;
 					nOffs  += nSize;
 					i++;
 				}
 				assert(i == nMips);
 				m_nMips = nMips;
 				pData[0] = pTemp;
 				SAFE_RELEASE(pSrcTexture);
 			}
 		}
 	}
 	assert(nWdt && nHgt && nMips);
 
 	D3DSurface *pSurf = NULL;
   CDeviceTexture *pDevTexture = NULL;
 
 	D3DTEXTUREFILTERTYPE MipFilter = D3DTEXF_LINEAR;
 	D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	// Create the video texture
 	if (m_eTT == eTT_2D)
 	{
 		if (m_eTFDst == eTF_DF16 || m_eTFDst == eTF_DF24 || m_eTFDst == eTF_D16 || m_eTFDst == eTF_D24S8)
 		{
 			// this is valid for FT_USAGE_DEPTHSTENCIL textures only
 			// TD for proper support D3DFMT_D24X8 format should be supported as separate DX9 format
 			if (D3DFmt == D3DFMT_D24S8)
 				D3DFmt=D3DFMT_D24X8;
 
 			//FIX: should pool be changed to the D3DPool
 			if (FAILED(hr=pDevMan->Create2DTexture (nWdt, nHgt, 1, D3DUSAGE_DEPTHSTENCIL, D3DFmt, D3DPOOL_DEFAULT, &pDevTexture)))
 			{
 				iLog->Log("Error: CTexture::CreateDeviceTexture: failed to create depthstencil texture %s (Error: %s)", GetSourceName(), r->D3DError(hr));
 				return false;
 			}
 		}
 		else
 		if (m_eTFDst != eTF_3DC)
 		{
 			resetSRGB = false;
 			m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0;
 #if !defined(XENON)
 			if (FAILED(hr=pDevMan->Create2DTexture(nWdt, nHgt, nMips, D3DUsage, D3DFmt, D3DPool, &pDevTexture)))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #endif
 			{
 			  iLog->Log("Error: CTexture::CreateDeviceTexture: failed to create the texture %s (%s)", GetSourceName(), r->D3DError(hr));
 			  assert(0);
 			  return false;
 			}
 
 
 
 
 
 
 		}
 		else
     if (m_eTFDst == eTF_3DC)
 		{
 #if !defined(XENON) && !defined(PS3)
 			int nM = 0;
 			int w = nWdt;
 			int h = nHgt;
 			if (w < 4 || h < 4)
 			{
 				iLog->Log("Error: 3DC texture '%s' couldn't be loaded due to small size (%dx%d) - skipped", GetName(), w, h);
 				return false;
 			}
 			while (w && h)
 			{
 				if (!w)
 					w = 1;
 				if (!h)
 					h = 1;
 				if (w >= 4 && h >= 4)
 					nM++;
 				w >>= 1;
 				h >>= 1;
 			}
 			nMips = min(nM, nMips);
 #endif
 			if (FAILED(hr=pDevMan->Create2DTexture(nWdt, nHgt, nMips, D3DUsage, D3DFmt, D3DPool, &pDevTexture)))
 			{
 				iLog->Log("Error: CD3D9TexMan::D3DCreateVideoTexture: failed to create the texture %s (%s)", GetSourceName(), r->D3DError(hr));
 				return false;
 			}
 		}
     SAFE_RELEASE(m_pDevTexture); 
 		m_pDevTexture = pDevTexture;
     if (m_pDevTexture) 
       m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}
 	else
   if (m_eTT == eTT_Cube)
 	{
 		if (!(r->m_pd3dCaps->TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
 		{
 			nMips = 1;
 			m_nMips = 1;
 		}
 		
 		resetSRGB = false;
 		m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0;
 		
 		D3DFormat D3DReadFormat = D3DFmt;
 
 
 
 
 
 
 
 
 
 
 
 		
 		if (FAILED(hr = pDevMan->CreateCubeTexture(nWdt, nMips, D3DUsage, D3DReadFormat, D3DPool, &pDevTexture)))
 			return false;
     SAFE_RELEASE(m_pDevTexture); 
 		m_pDevTexture = pDevTexture;
     if (m_pDevTexture) 
       m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
 	}
 	else
   if (m_eTT == eTT_3D)
 	{
 		if (!(r->m_pd3dCaps->TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
 		{
 			nMips = 1;
 			m_nMips = 1;
 		}
 		if (FAILED(hr = pDevMan->CreateVolumeTexture(nWdt, nHgt, nDepth, nMips, D3DUsage, D3DFmt, D3DPool, &pDevTexture)))
 			return false;
     SAFE_RELEASE(m_pDevTexture); 
 		m_pDevTexture = pDevTexture;
     if (m_pDevTexture) 
       m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
 	}
 	if (m_nFlags & FT_USAGE_MSAA)
 	{
 		assert(m_nFlags & FT_USAGE_RENDERTARGET);
 		hr = gcpRendD3D->GetDevice()->CreateRenderTarget(nWdt, nHgt, D3DFmt, r->m_RP.m_MSAAData.Type, r->m_RP.m_MSAAData.Quality, FALSE, &pSurf, NULL);
 		if (FAILED(hr))
 		{
 			assert(0);
 			iLog->LogError("Error: Cannot create MSAA render-target (MSAA switched off).");
 			_SetVar("r_MSAA", 0);
 		}
 		m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type;
 		m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality;
 		m_pDeviceRTV = pSurf;
 		m_bResolved = false;
 	}
 #elif defined (DIRECT3D10)
   STextureInfo TI;
   TI.m_nArraySize = m_nArraySize;
   assert(m_nArraySize<=4);
   D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat;
 	if (m_eTT == eTT_2D)
 	{
     //nMips = 1;
     DXGI_FORMAT nFormatOrig = D3DFmt;
     DXGI_FORMAT nFormatSRGB = D3DFmt;
 
     resetSRGB = false;
 #if !defined(PS3)
     {
       m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0;
       if ((m_bIsSRGB || m_nFlags & FT_USAGE_ALLOWREADSRGB))
         nFormatSRGB = ConvertToSRGBFmt(D3DFmt);
 
       if (m_bIsSRGB)
         D3DFmt = nFormatSRGB;
 
       // must use typeless format to allow runtime casting
       if (m_nFlags & FT_USAGE_ALLOWREADSRGB)
         D3DFmt = ConvertToTypelessFmt(D3DFmt);
     }
 #endif
 
     uint32 nUsage = 0;
 		if (m_nFlags & FT_USAGE_DEPTHSTENCIL)
       nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL;
     if (m_nFlags & FT_USAGE_RENDERTARGET)
       nUsage |= CDeviceManager::USAGE_RENDER_TARGET;
     if (m_nFlags & FT_USAGE_DYNAMIC)
       nUsage |= CDeviceManager::USAGE_DYNAMIC;
 		if( m_nFlags & FT_USAGE_READBACK )
 			nUsage |= CDeviceManager::USAGE_READBACK;
 
 		if (m_nFlags & FT_FORCE_MIPS)
     {
 			nUsage |= CDeviceManager::USAGE_AUTOGENMIPS;
       if (nMips <= 1) m_nMips = nMips = max(1, CTexture::CalcNumMips(nWdt, nHgt) - 2);
     }
 
 #if !defined(PS3) && !defined(CAFE)
 		if (m_nFlags & FT_USAGE_MSAA)
 		{
 			m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type;
 			m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality;
 
 			TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples;
 			TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality;
 			hr = pDevMan->Create2DTexture(nWdt, nHgt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI);
 
 			assert(SUCCEEDED(hr));
 			m_bResolved = false;
 
 			TI.m_nMSAASamples = 1;
 			TI.m_nMSAAQuality = 0;
 		}
 #endif
 
     if (pData[0])
 		{
 			assert(TI.m_nArraySize==1); //there is no implementation for tex array data
 
 			//if (!IsDXTCompressed(m_eTFSrc))
 			{
 				STextureInfoData InitData[20];
 				int w = nWdt;
 				int h = nHgt;
 				int nOffset = 0;
 				byte *src = pData[0];
 				for (i=0; i<nMips; i++)
 				{
 					if (!w && !h)
 						break;
 					if (!w) w = 1;
 					if (!h) h = 1;
 
 					int nSize = TextureDataSize(w, h, 1, 1, m_eTFSrc);
 					InitData[i].pSysMem = &src[nOffset];
 					if (!IsDXTCompressed(m_eTFSrc))
 						InitData[i].SysMemPitch = TextureDataSize(w, 1, 1, 1, m_eTFSrc);
 					else
 					{
 						int blockSize = (m_eTFSrc == eTF_DXT1 || m_eTFSrc == eTF_CTX1) ? 8 : 16;
 						InitData[i].SysMemPitch = (w + 3) / 4 * blockSize;
 					}
 
 					//ignored
 					InitData[i].SysMemSlicePitch = nSize;
 
 					w >>= 1;
 					h >>= 1;
 					nOffset += nSize;
 				}
 
         TI.m_pData = InitData;
 
         SAFE_RELEASE(m_pDevTexture); 
         hr = pDevMan->Create2DTexture(nWdt, nHgt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI);
         if (!FAILED(hr) && m_pDevTexture) 
           m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
 			}
 		}
 		else
 		{
 			//hr = dv->CreateTexture2D(&Desc, 0, 0); // validates parameters
 			//assert(hr == S_FALSE);
       SAFE_RELEASE(m_pDevTexture); 
       hr = pDevMan->Create2DTexture(nWdt, nHgt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI, false, m_nPriority);
       if (!FAILED(hr) && m_pDevTexture) 
         m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
 		}
 		
 		if (FAILED(hr))
 		{
 			assert(0);
 			return false;
 		}
 		
 		if ( m_nFlags&FT_USAGE_READBACK ) // readback texture, not compatible for shader resource view, return
 			return true;
 		
     // Restore format
     if (m_nFlags & FT_USAGE_ALLOWREADSRGB)
       D3DFmt = nFormatOrig;
 
     D3DDevice *dv = gcpRendD3D->m_pd3dDevice;
 
 		//////////////////////////////////////////////////////////////////////////
 		//ShaderResourceViews creation 
 #ifndef PS3
 		if (m_nFlags & FT_USAGE_MSAA && m_pRenderTargetData && m_pRenderTargetData->m_pDeviceTextureMSAA)
 		{
 			ID3D11ShaderResourceView* pSRVMS = NULL;
 			D3D11_SHADER_RESOURCE_VIEW_DESC SRVDescMS;
 			ZeroStruct(SRVDescMS);
       
 			SRVDescMS.Format = ConvertToShaderResourceFmt( D3DFmt );
 			SRVDescMS.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
 			hr = dv->CreateShaderResourceView(m_pRenderTargetData->m_pDeviceTextureMSAA->Get2DTexture(), &SRVDescMS, &pSRVMS);
 			if (FAILED(hr))
 			{
 				assert(0);
 				return false;
 			}
 			m_pRenderTargetData->m_pDeviceShaderResourceMS = pSRVMS;
 		}
 #endif
 
 		ID3D11ShaderResourceView *pSRV = NULL;    
 		ID3D11ShaderResourceView* ppSRVs[4] = { NULL }; 
 
 		D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
 		ZeroStruct(SRVDesc);
 		SRVDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt(D3DFmt);
     D3DTexture *pID3DTexture = m_pDevTexture->Get2DTexture();
 
 		if (m_nArraySize > 1)
 		{
 			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
 			SRVDesc.Texture2DArray.FirstArraySlice = 0;
 			SRVDesc.Texture2DArray.ArraySize = m_nArraySize;
 			SRVDesc.Texture2DArray.MipLevels = nMips;
 			SRVDesc.Texture2DArray.MostDetailedMip = 0;
 
 			// Create the multi-slice shader resource view
 			hr = dv->CreateShaderResourceView(pID3DTexture, &SRVDesc, &pSRV);
 			if (FAILED(hr))
 			{
 				assert(0);
 				return false;
 			}
 			// Create the one-slice shader resource views
 			SRVDesc.Texture2DArray.ArraySize = 1;
 			for( uint32 i = 0; i < m_nArraySize; ++i )
 			{
 				SRVDesc.Texture2DArray.FirstArraySlice = i;
 				hr = dv->CreateShaderResourceView( pID3DTexture, &SRVDesc, &ppSRVs[i]);
 				if (FAILED(hr))
 				{
 					assert(0);
 					return false;
 				}
 			}
 
 #ifndef PS3
 			//assign shader resource views
 			m_pDeviceShaderResource = pSRV;
 			for( uint32 i = 0; i < m_nArraySize; ++i )
 			{
 				m_pRenderTargetData->m_pShaderResourceViews[i] = ppSRVs[i];
 			}
 #endif
 		}
 		else
 		{
 			SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
 			SRVDesc.Texture2D.MipLevels = nMips;
 			SRVDesc.Texture2D.MostDetailedMip = 0;
 			hr = dv->CreateShaderResourceView(pID3DTexture, &SRVDesc, &pSRV);
 			if (FAILED(hr))
 			{
 				assert(0);
 				return false;
 			}
 			//assign shader resource views
 			m_pDeviceShaderResource = pSRV;
 
 #if !defined(PS3)
       if( m_nFlags & FT_USAGE_ALLOWREADSRGB )
       {
         SRVDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt( nFormatSRGB );
 
         ID3D11ShaderResourceView *pSRVSRGB = NULL;
         hr = dv->CreateShaderResourceView(pID3DTexture, &SRVDesc, &pSRVSRGB);
         if (FAILED(hr))
         {
           assert(0);
           return false;
         }
         //assign shader resource views
         m_pDeviceShaderResourceSRGB = pSRVSRGB;
       }
 #endif
 		}
 
 		//////////////////////////////////////////////////////////////////////////
 		// Vertex buffer creation (R2VB feature for PS3)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		//////////////////////////////////////////////////////////////////////////
 		//DepthStencilViews creation
 		ID3D11DepthStencilView* pDSV = NULL;
 		ID3D11DepthStencilView* ppDSVs[4];
 		for( int i = 0; i < 4; ++i ) ppDSVs[i] = NULL;
 
 		if (m_nFlags & FT_USAGE_DEPTHSTENCIL)
 		{
 			D3D11_DEPTH_STENCIL_VIEW_DESC DsvDesc;
 			ZeroStruct(DsvDesc);
 			DsvDesc.Format = (DXGI_FORMAT)ConvertToDepthStencilFmt( D3DFmt );
 
 			if (m_nArraySize > 1)
 			{
 				DsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
 				DsvDesc.Texture2DArray.FirstArraySlice = 0;
 				DsvDesc.Texture2DArray.ArraySize = m_nArraySize;
 				DsvDesc.Texture2DArray.MipSlice = 0;
 
 				//multi-faces render target view
 				hr = dv->CreateDepthStencilView(pID3DTexture, &DsvDesc, &pDSV);
 				if (FAILED(hr) )
 				{
 					assert(0);
 					return false;
 				}
 
 				// Create the one-face render target views
 				DsvDesc.Texture2DArray.ArraySize = 1;
 				for( uint32 i = 0; i < m_nArraySize; ++i )
 				{
 					DsvDesc.Texture2DArray.FirstArraySlice = i;
 					hr = dv->CreateDepthStencilView( pID3DTexture, &DsvDesc, &ppDSVs[i] );
 					if (FAILED(hr) )
 					{
 						assert(0);
 						return false;
 					}
 				}
 
 				//assign depth stencil views
 				m_pRenderTargetData->m_pDeviceDepthStencilSurf = pDSV;
 				for( uint32 i = 0; i < m_nArraySize; ++i )
 				{
 					m_pRenderTargetData->m_pDeviceDepthStencilCMSurfs[i] = ppDSVs[i];
 				}
 			}
 			else
 			{
 				DsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
 				DsvDesc.Texture2D.MipSlice = 0;
 				hr = dv->CreateDepthStencilView(pID3DTexture, &DsvDesc, &pDSV);
 				if (FAILED(hr) )
 				{
 					assert(0);
 					return false;
 				}
 				m_pRenderTargetData->m_pDeviceDepthStencilSurf = pDSV;
 			}
 		}
 	}
 	else
   if (m_eTT == eTT_Cube)
 	{
     STextureInfo TI;
     TI.m_nArraySize = 6;
     D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat;
     uint32 nUsage = 0;
     if (m_nFlags & FT_USAGE_DEPTHSTENCIL)
       nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL;
     if (m_nFlags & FT_USAGE_RENDERTARGET)
       nUsage |= CDeviceManager::USAGE_RENDER_TARGET;
     if (m_nFlags & FT_USAGE_DYNAMIC)
       nUsage |= CDeviceManager::USAGE_DYNAMIC;
 
 #ifndef PS3
     if (m_nFlags & FT_USAGE_MSAA)
     {
       m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type;
       m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality;
 
       TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples;
       TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality;
       hr = pDevMan->CreateCubeTexture(nWdt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI);
 
       assert(SUCCEEDED(hr));
       m_bResolved = false;
 
       TI.m_nMSAASamples = 1;
       TI.m_nMSAAQuality = 0;
     }
 #endif
     DXGI_FORMAT nFormatOrig = D3DFmt;
     DXGI_FORMAT nFormatSRGB = D3DFmt;
 
     resetSRGB = false;
 
 #if !defined(PS3)
     {
       m_bIsSRGB &= m_pPixelFormat->bCanReadSRGB && (m_nFlags & (FT_USAGE_MSAA | FT_USAGE_RENDERTARGET)) == 0;
 
       if ((m_bIsSRGB || m_nFlags & FT_USAGE_ALLOWREADSRGB))
         nFormatSRGB = ConvertToSRGBFmt(D3DFmt);
 
       if (m_bIsSRGB)
         D3DFmt = nFormatSRGB;
 
       // must use typeless format to allow runtime casting
       if (m_nFlags & FT_USAGE_ALLOWREADSRGB)
         D3DFmt = ConvertToTypelessFmt(D3DFmt);
     }
 #endif
 
     if (pData[0])
     {
       STextureInfoData InitData[g_nD3D10MaxSupportedSubres];
 
       for (int nSide=0; nSide<6; nSide++)
       {
         int w = nWdt;
         int h = nHgt;
         int nOffset = 0;
         byte *src = (!(m_nFlags & FT_REPLICATE_TO_ALL_SIDES)) ? pData[nSide] : pData[0];
 
         for (i=0; i<nMips; i++)
         {
           if (!w && !h)
             break;
           if (!w) w = 1;
           if (!h) h = 1;
 
           int nSubresInd = nSide * nMips + i;
           int nSize = TextureDataSize(w, h, 1, 1, m_eTFSrc);
           InitData[nSubresInd].pSysMem = &src[nOffset];
 
           InitData[nSubresInd].SysMemPitch = TextureDataSize(w, 1, 1, 1, m_eTFSrc);
 
           //ignored
           InitData[nSubresInd].SysMemSlicePitch = nSize;
 
           w >>= 1;
           h >>= 1;
           nOffset += nSize;
         }
       }
 
 			TI.m_pData = InitData;
       SAFE_RELEASE(m_pDevTexture); 
       hr = pDevMan->CreateCubeTexture(nWdt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI);
       if (!FAILED(hr) && m_pDevTexture) 
         m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
     }
     else
     {
       //hr = dv->CreateTexture2D(&Desc, 0, 0); // validates parameters
       //assert(hr == S_FALSE);
       SAFE_RELEASE(m_pDevTexture); 
       hr = pDevMan->CreateCubeTexture(nWdt, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI);
       if (!FAILED(hr) && m_pDevTexture) 
         m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
     }
 		if (FAILED(hr))
 		{
 			assert(0);
 			return false;
 		}
 
 		if (m_nFlags & FT_USAGE_ALLOWREADSRGB)
 			D3DFmt = nFormatOrig;
 
 		D3DCubeTexture *pID3DTexture = m_pDevTexture->GetCubeTexture();
     D3DDevice *dv = gcpRendD3D->m_pd3dDevice;
 
 		ID3D11ShaderResourceView *pRes = NULL;
 		D3D11_SHADER_RESOURCE_VIEW_DESC ResDesc;
 		ZeroStruct(ResDesc);
 		ResDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt( D3DFmt );
 		ResDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
 		ResDesc.TextureCube.MipLevels = nMips;
 		ResDesc.TextureCube.MostDetailedMip = 0;
 		hr = dv->CreateShaderResourceView(pID3DTexture, &ResDesc, &pRes);
 		if (FAILED(hr))
 		{
 			assert(0);
 			return false;
 		}
 		m_pDeviceShaderResource = pRes;
 
 #if !defined(PS3)
     if( m_nFlags & FT_USAGE_ALLOWREADSRGB )
     {
       ResDesc.Format = (DXGI_FORMAT)ConvertToShaderResourceFmt( nFormatSRGB );
 
       ID3D11ShaderResourceView *pSRGBRes = NULL;
       hr = dv->CreateShaderResourceView(pID3DTexture, &ResDesc, &pSRGBRes);
       if (FAILED(hr))
       {
         assert(0);
         return false;
       }
       //assign shader resource views
       m_pDeviceShaderResourceSRGB = pSRGBRes;
     }
 #endif
 
 		//depth-stencil views for cubemaps
 		if (m_nFlags & FT_USAGE_DEPTHSTENCIL)
 		{
 			ID3D11DepthStencilView* pDSV = NULL;
 			ID3D11DepthStencilView* ppDSVs[6];
 
 			for( int i = 0; i < 6; ++i ) ppDSVs[i] = NULL;
 			D3D11_DEPTH_STENCIL_VIEW_DESC DsvDesc;
 			ZeroStruct(DsvDesc);
 			DsvDesc.Format = (DXGI_FORMAT)ConvertToDepthStencilFmt( D3DFmt );
 			DsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
 			DsvDesc.Texture2DArray.FirstArraySlice = 0;
 			DsvDesc.Texture2DArray.ArraySize = 6;
 			DsvDesc.Texture2DArray.MipSlice = 0;
 
 			//six-faces render target view
 			hr = dv->CreateDepthStencilView(pID3DTexture, &DsvDesc, &pDSV);
 			if (FAILED(hr) )
 			{
 				assert(0);
 				return false;
 			}
 
 			// Create the one-face render target views
 			DsvDesc.Texture2DArray.ArraySize = 1;
 			DsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
 			for( int i = 0; i < 6; ++i )
 			{
 				DsvDesc.Texture2DArray.FirstArraySlice = i;
 				hr = dv->CreateDepthStencilView( pID3DTexture, &DsvDesc, &ppDSVs[i] );
 				if (FAILED(hr) )
 				{
 					assert(0);
 					return false;
 				}
 			}
 			//assign depth stencil views
 			m_pRenderTargetData->m_pDeviceDepthStencilSurf = pDSV;
 
 			for( int i = 0; i < 6; ++i )
 			{
 				m_pRenderTargetData->m_pDeviceDepthStencilCMSurfs[i] = ppDSVs[i];
 			}
 		}
 	}
 	else
   if( m_eTT == eTT_3D)
 	{
     STextureInfo TI;
     TI.m_nArraySize = 1;
     D3DFormat D3DFmt = m_pPixelFormat->DeviceFormat;
 
     uint32 nUsage = 0;
     if (m_nFlags & FT_USAGE_DEPTHSTENCIL)
       nUsage |= CDeviceManager::USAGE_DEPTH_STENCIL;
     if (m_nFlags & FT_USAGE_RENDERTARGET)
       nUsage |= CDeviceManager::USAGE_RENDER_TARGET;
     if (m_nFlags & FT_USAGE_DYNAMIC)
       nUsage |= CDeviceManager::USAGE_DYNAMIC;
 
 #ifndef PS3
 		if (m_nFlags & FT_USAGE_MSAA)
     {
       m_pRenderTargetData->m_nMSAASamples = (uint8)r->m_RP.m_MSAAData.Type;
       m_pRenderTargetData->m_nMSAAQuality = (uint8)r->m_RP.m_MSAAData.Quality;
 
       TI.m_nMSAASamples = m_pRenderTargetData->m_nMSAASamples;
       TI.m_nMSAAQuality = m_pRenderTargetData->m_nMSAAQuality;
       hr = pDevMan->CreateVolumeTexture(nWdt, nHgt, m_nDepth, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pRenderTargetData->m_pDeviceTextureMSAA, &TI);
 
       assert(SUCCEEDED(hr));
       m_bResolved = false;
 
       TI.m_nMSAASamples = 1;
       TI.m_nMSAAQuality = 0;
     }
 #endif
     if (pData[0])
     {
       STextureInfoData InitData[15];
 
       int w = nWdt;
       int h = nHgt;
       int d = nDepth;
       int nOffset = 0;
       byte *src = pData[0];
 
       for (i=0; i<nMips; i++)
       {
         if (!w && !h && !d)
           break;
         if (!w) w = 1;
         if (!h) h = 1;
         if (!d) d = 1;
 
 				int nSliceSize = TextureDataSize(w, h, 1, 1, m_eTFSrc);
 				int nMipSize = TextureDataSize(w, h, d, 1, m_eTFSrc);
         InitData[i].pSysMem = &src[nOffset];
         InitData[i].SysMemPitch = TextureDataSize(w, 1, 1, 1, m_eTFSrc);
 
         //ignored
         InitData[i].SysMemSlicePitch = nSliceSize;
 
         w >>= 1;
         h >>= 1;
         d >>= 1;
 
         nOffset += nMipSize;
       }
 
 			TI.m_pData = InitData;
       SAFE_RELEASE(m_pDevTexture); 
       hr = pDevMan->CreateVolumeTexture(nWdt, nHgt, nDepth, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI);
       if (!FAILED(hr) && m_pDevTexture) 
         m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
     }
     else
     {
       //hr = dv->CreateTexture2D(&Desc, 0, 0); // validates parameters
       //assert(hr == S_FALSE);
       SAFE_RELEASE(m_pDevTexture); 
       hr = pDevMan->CreateVolumeTexture(nWdt, nHgt, nDepth, nMips, nUsage, D3DFmt, (D3DPOOL)0, &m_pDevTexture, &TI);
       if (!FAILED(hr) && m_pDevTexture) 
         m_pDevTexture->SetNoDelete(!!(m_nFlags & FT_DONT_RELEASE));
     }
 		if(SUCCEEDED(hr))
 		{
 			D3DVolumeTexture *pID3DTexture3D = m_pDevTexture->GetVolumeTexture();
 			D3DDevice *dv = gcpRendD3D->m_pd3dDevice;
 
 			ID3D11ShaderResourceView *pRes = NULL;
 			D3D11_SHADER_RESOURCE_VIEW_DESC ResDesc;
 			ZeroStruct(ResDesc);
 			ResDesc.Format = D3DFmt;
 			ResDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
 			ResDesc.Texture3D.MipLevels = nMips;
 			ResDesc.Texture3D.MostDetailedMip = 0;
 			hr = dv->CreateShaderResourceView(pID3DTexture3D, &ResDesc, &pRes);
 			if (FAILED(hr))
 			{
 				assert(0);
 				return false;
 			}
 			m_pDeviceShaderResource = pRes;
 		}
 		else
 		{
 			assert(0);
 			return false;
 		}
 	}
 	else 
 	{
 		assert(0);
 		return false;
 	}
 #endif
 
 	SetTexStates();
 
 	assert(!IsStreamed());
 	if (m_pDevTexture)
 	{
 		m_nActualSize = CTexture::TextureDataSize(nWdt, nHgt, nDepth, nMips, m_eTFDst);
 		m_nActualSize *= m_nArraySize;
 		if(m_eTT == eTT_Cube) m_nActualSize *= 6;
 		if (m_nFlags & (FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET))
 			CryInterlockedAdd(CTexture::s_nStatsCurDynamicTexMem.Addr(), m_nActualSize);
 		else	
 			CryInterlockedAdd(CTexture::s_nStatsCurManagedNonStreamedTexMem.Addr(), m_nActualSize);
 
 	}
 
 
 
 
 
 
 	if (!pData[0])
 		return true;
 
 	int nOffset = 0;
 #if defined (DIRECT3D9)
 	if (m_eTT == eTT_3D)
 	{
     D3DVolumeTexture *pID3DVolTexture = pDevTexture->GetVolumeTexture();
 		// Fill the volume texture
 		D3DLOCKED_BOX LockedBox;
 
 		int w = nWdt;
 		int h = nHgt;
 		int d = nDepth;
 		nOffset = 0;
 		byte *src = pData[0];
 
 
 
 
 
 
 
 		for (i=0; i<m_nMips; i++)
 		{
 			if (!w && !h && !d)
 				break;
 			hr = pID3DVolTexture->LockBox(i, &LockedBox, 0, 0);
 			assert(SUCCEEDED(hr));
 			if (!w) w = 1;
 			if (!h) h = 1;
 			if (!d) d = 1;
 			const int nSliceSize = TextureDataSize(w, h, 1, 1, m_eTFDst);
 			const int nPitch = TextureDataSize(w, 1, 1, 1, m_eTFDst);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 			for (int r=0; r<d; r++)
 			{
 				byte* pSliceStart = (byte*)LockedBox.pBits;
 				for (int t=0; t<h; t++)
 				{
 					memcpy((byte *)LockedBox.pBits, &src[nOffset], nPitch);
 					LockedBox.pBits = (BYTE*)LockedBox.pBits + LockedBox.RowPitch;
 					nOffset += nPitch;
 				}
 				LockedBox.pBits = pSliceStart + LockedBox.SlicePitch;
 			}
 
 			w >>= 1;
 			h >>= 1;
 			d >>= 1;
 
 			pID3DVolTexture->UnlockBox(i);
 		}
 	}
 	else
 	if (m_eTT == eTT_Cube)
 	{
 		for (int nSide=0; nSide<6; nSide++)
 		{
 			int w = nWdt;
 			int h = nHgt;
 			nOffset = 0;
 			byte *src = pData[nSide];
 			for (i=0; i<m_nMips; i++)
 			{
 				if (!w && !h)
 					break;
 
 				const bool isNative = w > 64 && h > 64 && !(m_nFlags & FT_TEX_WAS_NOT_PRE_TILED);
 
 				if (!w) w = 1;
 				if (!h) h = 1;
 				const int nSize = TextureDataSize(w, h, 1, 1, m_eTFDst);
 
 				if (nSide && !src && (m_nFlags & FT_REPLICATE_TO_ALL_SIDES))
           src = pData[0];
 				hr = pDevTexture->LockRect(nSide, i, lr, 0);
 				assert(SUCCEEDED(hr));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 				cryMemcpy((byte *)lr.pData, &src[nOffset], nSize); 
 
 				pDevTexture->UnlockRect(nSide, i);
 
         w >>= 1;
 				h >>= 1;
 				nOffset += nSize;
 			}
 		}
 	}
   else
 	if (m_eTT == eTT_2D)
 	{
 		int w = nWdt;
 		int h = nHgt;
 		nOffset = 0;
 		byte *src = pData[0];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 		for (i=0; i<nMips; i++)
 		{
 			if (!w && !h)
 				break;
 			if (!w) w = 1;
 			if (!h) h = 1;
 			const int nSize = TextureDataSize(w, h, 1, 1, m_eTFDst);
 			bool bLoaded = false;
 			hr = pDevTexture->LockRect(i, lr, 0);
 			assert(SUCCEEDED(hr));
 			if(FAILED(hr) || !lr.pData)
 				continue;
 #ifdef _DEBUG
 			if (w >= 4)
 			{
 				int nD3DSize;
 				if (IsDXTCompressed(GetDstFormat()))
 					nD3DSize = CTexture::TextureDataSize(w, h, 1, 1, GetDstFormat());
 				else
 					nD3DSize = lr.Pitch * h;
 				assert(nD3DSize >= nSize);
 			}
 #endif
 			if (w < 4 && !IsDXTCompressed(m_eTFDst))
 			{
 				int nD3DSize = lr.Pitch * h;
 				if (nD3DSize != nSize)
 				{
 					bLoaded = true;
 					byte *pDst = (byte *)lr.pData;
 					byte *pSrc = &src[nOffset];
 					const int nPitchSrc = CTexture::TextureDataSize(w, 1, 1, 1, m_eTFDst);
 					for (int j=0; j<h; j++)
 					{
 						memcpy(pDst, pSrc, nPitchSrc);
 						pSrc += nPitchSrc;
 						pDst += lr.Pitch;
 					}
 				}
 			}
 			if (!bLoaded)
 			{
 				cryMemcpy((byte *)lr.pData, &src[nOffset], nSize);
 			}
 			pDevTexture->UnlockRect(i);
 			w >>= 1;
 			h >>= 1;
 			nOffset += nSize;
 		}
 
 	}
 #endif
 
 	if (resetSRGB)
 		m_bIsSRGB = false;
 
 	SetWasUnload(false);
 
 	SAFE_DELETE_ARRAY(pTemp);
 	return true;
 }
 
 void CTexture::ReleaseDeviceTexture(bool bKeepLastMips)
 {
 	PROFILE_FRAME(CTexture_ReleaseDeviceTexture);
 
   Unbind();
 
 	if(!gcpRendD3D->m_pRT->IsRenderThread())
 	{
 		if(!gcpRendD3D->m_pRT->IsMainThread())
 			CryFatalError("Texture is deleted from non-main and non-render thread, which causes command buffer corruption!");
 		// we need to flush the pipeline in order to prevent some concurrent list modifications
 		gcpRendD3D->m_pRT->FlushAndWait();
 	}
 
 	AbortStreamingTasks(this);
 
   if (m_bStreamRequested)
   {
     for (uint32 i=0; i<s_StreamingRequested.size(); i++)
     {
       if (s_StreamingRequested[i] == this)
       {
         s_StreamingRequested.erase(s_StreamingRequested.begin() + i);
         break;
       }
     }
 		m_bStreamRequested = false;
   }
 
   if (!m_bNoTexture)
 	{
 		CDeviceTexture *pTex = m_pDevTexture;
 
 #if defined(XENON) || (defined PS3)// for X360, ps3 and streamed textures, the pool item manages the lifetime of device texture
 
 
 
 
 
 
 
 
 
 
 		if(!m_pFileTexMips || !m_pFileTexMips->m_pPoolItem)
 		{
 #     if defined (DIRECT3D10)
  		  ID3D11ShaderResourceView* pSRV = (ID3D11ShaderResourceView*)m_pDeviceShaderResource;
 		  SAFE_RELEASE( pSRV );
 		  m_pDeviceShaderResource = NULL;
 #     endif 
 		  if (IsStreamed())
 			{
 
 
 
 
 
 
 
 				SAFE_DELETE(pTex);			// for manually created textures
 			}
 			else
 			{
 
 
 
 
 				SAFE_RELEASE(pTex);
 			}
     }
   #else
     SAFE_RELEASE(pTex); 
   #endif 
 
 #if defined (DIRECT3D10)
 #ifndef PS3
     ID3D11ShaderResourceView* pSRVSRGB = (ID3D11ShaderResourceView*)m_pDeviceShaderResourceSRGB;
     SAFE_RELEASE( pSRVSRGB );
     m_pDeviceShaderResourceSRGB = NULL;
 #endif
 
 #if defined(WIN32) || defined(WIN64)
 		ID3D11ShaderResourceView* pSRV = (ID3D11ShaderResourceView*) m_pDeviceShaderResource;
 		SAFE_RELEASE(pSRV);
 		m_pDeviceShaderResource = 0;
 #endif
 
 		ID3D11RenderTargetView* pRTV = (ID3D11RenderTargetView*)m_pDeviceRTV;
 		SAFE_RELEASE( pRTV );
 		m_pDeviceRTV = NULL;
 
     ID3D11RenderTargetView* pRTVMS = (ID3D11RenderTargetView*)m_pDeviceRTVMS;
     SAFE_RELEASE( pRTVMS );
     m_pDeviceRTVMS = NULL;
 
 #else
 		LPDIRECT3DSURFACE9 pSurf = (LPDIRECT3DSURFACE9)m_pDeviceRTV;
 		if (pSurf)
 		{
 			SAFE_RELEASE(pSurf);
 			m_pDeviceRTV = NULL;
 		}
 #endif
 
 		m_pDevTexture = NULL;
 		// otherwise it's already taken into account in the m_pFileTexMips->m_pPoolItem's dtor
 		if(!m_pFileTexMips || !m_pFileTexMips->m_pPoolItem)
 		{
 			if (IsStreamed())
 			{
 				assert(CTexture::s_nStatsCurManagedStreamedTexMem >= m_nActualSize);
 				CryInterlockedAdd(CTexture::s_nStatsCurManagedStreamedTexMem.Addr(), -m_nActualSize);
         CryInterlockedAdd(CTexture::s_nStatsCurManagedStreamedSysTexMem.Addr(), -m_nFullSize);
 			}
 			else if (IsDynamic())
 			{
 				assert(CTexture::s_nStatsCurDynamicTexMem >= m_nActualSize);
 				CryInterlockedAdd(CTexture::s_nStatsCurDynamicTexMem.Addr(), -m_nActualSize);
 			}
 			else
 			{
 				assert(CTexture::s_nStatsCurManagedNonStreamedTexMem >= m_nActualSize);
 				CryInterlockedAdd(CTexture::s_nStatsCurManagedNonStreamedTexMem.Addr(), -m_nActualSize);
 			}
 		}
 		int nSides = m_eTT == eTT_Cube ? 6 : 1;
 		if (m_pFileTexMips)
 		{
 			Unlink();
 			m_bStreamPrepared = false;
 			StreamRemoveFromPool();
 			if (bKeepLastMips)
 			{
 				const int nLastMipsStart = m_nMips - 1 - m_CacheFileHeader.m_nMipsPersistent;
 				for (int nS=0; nS<nSides; nS++)
 				{
 					for (int i=0; i<m_nMips; i++)
 					{
 						SMipData *mp = &m_pFileTexMips->m_pMipHeader[i].m_Mips[nS];
 						if (i < nLastMipsStart)
 							mp->Free();
 					}
 				}
 			}
 			else
 			{
 				SAFE_DELETE(m_pFileTexMips);
 				m_bStreamed = false;
 				SetStreamingInProgress(false);
 				m_bStreamRequested = false;
 			}
 		}
 		m_nActualSize = 0;
 	}
 	else
 	{
 		m_pDevTexture = NULL;
 		m_pDeviceRTV = NULL;
 #if defined (DIRECT3D10)
 		m_pDeviceShaderResource = NULL;
 #ifndef PS3
 		m_pDeviceShaderResourceSRGB = NULL;
 #endif
 #endif
 	}
 	m_bNoTexture = false;
 
 	// release vertex buffer binded to this texture (R2VB feature)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	SAFE_DELETE(m_pRenderTargetData);
 }
 
 void CTexture::SetTexStates()
 {
 	s_sDefState = s_sGlobalDefState;
 	if (m_nFlags & FT_FILTER_MASK)
 	{
 		int nFilter = m_nFlags & FT_FILTER_MASK;
 		if (nFilter == FT_FILTER_POINT)
 			SetFilter(FILTER_POINT);
 		else
     if (nFilter == FT_FILTER_LINEAR)
       SetFilter(FILTER_LINEAR);
     else
     if (nFilter == FT_FILTER_BILINEAR)
       SetFilter(FILTER_BILINEAR);
     else
     if (nFilter == FT_FILTER_TRILINEAR)
       SetFilter(FILTER_TRILINEAR);
     else
     if (nFilter == FT_FILTER_ANISO2)
       SetFilter(FILTER_ANISO2X);
     else
     if (nFilter == FT_FILTER_ANISO4)
       SetFilter(FILTER_ANISO4X);
     else
     if (nFilter == FT_FILTER_ANISO8)
       SetFilter(FILTER_ANISO8X);
     else
     if (nFilter == FT_FILTER_ANISO16)
       SetFilter(FILTER_ANISO16X);
 	}
 	if (m_nMips <= 1 && !(m_nFlags & FT_FORCE_MIPS))
 		s_sDefState.m_nMipFilter = 0; //D3DTEXF_NONE;
 	if (m_nFlags & FT_STATE_CLAMP || m_eTT == eTT_Cube)
 		SetClampingMode(TADDR_CLAMP, TADDR_CLAMP, TADDR_CLAMP);
 	m_nDefState = CTexture::GetTexState(s_sDefState);
 }
 
 static signed char sAddressMode(int nAddress)
 {
 	signed char nMode = -1;
 	if (nAddress < 0)
 		return nMode;
 #if defined (DIRECT3D9)
 	switch (nAddress)
 	{
 	case TADDR_WRAP:
 		nMode = D3DTADDRESS_WRAP;
 		break;
 	case TADDR_CLAMP:
 		nMode = D3DTADDRESS_CLAMP;
 		break;
 	case TADDR_BORDER:
 		nMode = D3DTADDRESS_BORDER;
 		break;
 	case TADDR_MIRROR:
 		nMode = D3DTADDRESS_MIRROR;
 		break;
 	default:
 		assert(0);
 		return D3DTADDRESS_WRAP;
 	}
 #elif defined (DIRECT3D10)
 	switch (nAddress)
 	{
 	case TADDR_WRAP:
 		nMode = D3D11_TEXTURE_ADDRESS_WRAP;
 		break;
 	case TADDR_CLAMP:
 		nMode = D3D11_TEXTURE_ADDRESS_CLAMP;
 		break;
 	case TADDR_BORDER:
 		nMode = D3D11_TEXTURE_ADDRESS_BORDER;
 		break;
 	case TADDR_MIRROR:
 		nMode = D3D11_TEXTURE_ADDRESS_MIRROR;
 		break;
 	default:
 		assert(0);
 		return D3D11_TEXTURE_ADDRESS_WRAP;
 	}
 #endif
 	return nMode;
 }
 
 void STexState::SetComparisonFilter(bool bEnable)
 {
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		SAFE_RELEASE(pSamp);
 		m_pDeviceState = NULL;
 	}
 #endif
 	m_bComparison = bEnable;
 }
 
 bool STexState::SetClampMode(int nAddressU, int nAddressV, int nAddressW)
 {
 
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		SAFE_RELEASE(pSamp);
 		m_pDeviceState = NULL;
 	}
 #endif
 
 	m_nAddressU = sAddressMode(nAddressU);
 	m_nAddressV = sAddressMode(nAddressV);
 	m_nAddressW = sAddressMode(nAddressW);
 	if (m_nAddressU < 0)
 		m_nAddressU = CTexture::s_TexStates[CTexture::s_nGlobalDefState].m_nAddressU;
 	if (m_nAddressV < 0)
 		m_nAddressV = CTexture::s_TexStates[CTexture::s_nGlobalDefState].m_nAddressV;
 	if (m_nAddressW < 0)
 		m_nAddressW = CTexture::s_TexStates[CTexture::s_nGlobalDefState].m_nAddressW;
 	return true;
 }
 
 bool STexState::SetFilterMode(int nFilter)
 {
 	if (nFilter < 0)
 	{
 		STexState *pTS = &CTexture::s_TexStates[CTexture::s_nGlobalDefState];
 		m_nMinFilter = pTS->m_nMinFilter;
 		m_nMagFilter = pTS->m_nMagFilter;
 		m_nMipFilter = pTS->m_nMipFilter;
 		return true;
 	}
 
 #if defined (DIRECT3D9)
 	switch(nFilter)
 	{
 	case FILTER_NONE:
 		m_nMinFilter = D3DTEXF_POINT;
 		m_nMagFilter = D3DTEXF_POINT;
 		m_nMipFilter = D3DTEXF_NONE;
 		break;
 	case FILTER_POINT:
 		m_nMinFilter = D3DTEXF_POINT;
 		m_nMagFilter = D3DTEXF_POINT;
 		m_nMipFilter = D3DTEXF_POINT;
 		break;
 	case FILTER_LINEAR:
 		m_nMinFilter = D3DTEXF_LINEAR;
 		m_nMagFilter = D3DTEXF_LINEAR;
 		m_nMipFilter = D3DTEXF_NONE;
 		break;
 	case FILTER_BILINEAR:
 		m_nMinFilter = D3DTEXF_LINEAR;
 		m_nMagFilter = D3DTEXF_LINEAR;
 		m_nMipFilter = D3DTEXF_POINT;
 		break;
 	case FILTER_TRILINEAR:
 		m_nMinFilter = D3DTEXF_LINEAR;
 		m_nMagFilter = D3DTEXF_LINEAR;
 		m_nMipFilter = D3DTEXF_LINEAR;
 		break;
 	case FILTER_ANISO2X:
 	case FILTER_ANISO4X:
 	case FILTER_ANISO8X:
 	case FILTER_ANISO16X:
 		if (gcpRendD3D->m_pd3dCaps)
 		{
 		if (gcpRendD3D->m_pd3dCaps->TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
 			m_nMinFilter = D3DTEXF_ANISOTROPIC;
 		else
 			m_nMinFilter = D3DTEXF_LINEAR;
 
 		if (gcpRendD3D->m_pd3dCaps->TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC)
 			m_nMagFilter = D3DTEXF_ANISOTROPIC;
 		else
 			m_nMagFilter = D3DTEXF_LINEAR;
 
 		m_nMipFilter = D3DTEXF_LINEAR;
 
 		if (nFilter == FILTER_ANISO2X)
 			m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 2);
 			else if (nFilter == FILTER_ANISO4X)
 			m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 4);
 			else if (nFilter == FILTER_ANISO8X)
 			m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 8);
 			else if (nFilter == FILTER_ANISO16X)
 			m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 16);
 
 		} else {
 			m_nMinFilter = D3DTEXF_LINEAR;
 			m_nMagFilter = D3DTEXF_LINEAR;
 			m_nMipFilter = D3DTEXF_LINEAR;
 		}
 		
 		break;
 	default:
 		assert(0);
 		return false;
 	}
 #elif defined (DIRECT3D10)
 
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		SAFE_RELEASE(pSamp);
 		m_pDeviceState = NULL;
 	}
 
 	switch(nFilter)
 	{
 	case FILTER_POINT:
 	case FILTER_NONE:
 		m_nMinFilter = FILTER_POINT;
 		m_nMagFilter = FILTER_POINT;
 		m_nMipFilter = FILTER_NONE;
 		break;
 	case FILTER_LINEAR:
 		m_nMinFilter = FILTER_LINEAR;
 		m_nMagFilter = FILTER_LINEAR;
 		m_nMipFilter = FILTER_NONE;
 		break;
 	case FILTER_BILINEAR:
 		m_nMinFilter = FILTER_LINEAR;
 		m_nMagFilter = FILTER_LINEAR;
 		m_nMipFilter = FILTER_POINT;
 		break;
 	case FILTER_TRILINEAR:
 		m_nMinFilter = FILTER_LINEAR;
 		m_nMagFilter = FILTER_LINEAR;
 		m_nMipFilter = FILTER_LINEAR;
 		break;
 	case FILTER_ANISO2X:
 	case FILTER_ANISO4X:
 	case FILTER_ANISO8X:
 	case FILTER_ANISO16X:
 		m_nMinFilter = nFilter;
 		m_nMagFilter = nFilter;
 		m_nMipFilter = nFilter;
 		if (nFilter == FILTER_ANISO2X)
 			m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 2);
 		else
 			if (nFilter == FILTER_ANISO4X)
 				m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 4);
 			else
 				if (nFilter == FILTER_ANISO8X)
 					m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 8);
 				else
 					if (nFilter == FILTER_ANISO16X)
 						m_nAnisotropy = min(gcpRendD3D->m_MaxAnisotropyLevel, 16);
 		break;
 	default:
 		assert(0);
 		return false;
 	}
 #endif
 	return true;
 }
 
 void STexState::SetBorderColor(DWORD dwColor) 
 { 
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		SAFE_RELEASE(pSamp);
 		m_pDeviceState = NULL;
 	}
 #endif
 
 	m_dwBorderColor = dwColor; 
 }
 
 void STexState::PostCreate()
 {
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 		return;
 
 	D3D11_SAMPLER_DESC Desc;
 	ZeroStruct(Desc);
 	ID3D11SamplerState *pSamp = NULL;
 	Desc.AddressU = (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressU;
 	Desc.AddressV = (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressV;
 	Desc.AddressW = (D3D11_TEXTURE_ADDRESS_MODE)m_nAddressW;
 	ColorF col((uint32)m_dwBorderColor);
 	Desc.BorderColor[0] = col.r;
 	Desc.BorderColor[1] = col.g;
 	Desc.BorderColor[2] = col.b;
 	Desc.BorderColor[3] = col.a;
 	if (m_bComparison)
 		Desc.ComparisonFunc = D3D11_COMPARISON_LESS;
 	else
 		Desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
 
 	Desc.MaxAnisotropy = 1;
 	Desc.MinLOD = 0;
   if (m_nMipFilter == FILTER_NONE)
   {
     Desc.MaxLOD = 0.0f;
   }
   else
   {
     Desc.MaxLOD = 100.0f;
   }
 
 	Desc.MipLODBias = 0;
 
 	if (m_bComparison)
 	{
 
 		if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && m_nMipFilter == FILTER_LINEAR || m_nMinFilter == FILTER_TRILINEAR || m_nMagFilter == FILTER_TRILINEAR)
 		{
 			Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_LINEAR;
 		}
 		else
 			if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT) || m_nMinFilter == FILTER_BILINEAR || m_nMagFilter == FILTER_BILINEAR)
 				Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;											
 			else
 				if (m_nMinFilter == FILTER_POINT && m_nMagFilter == FILTER_POINT && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT))
 					Desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_MIP_POINT;
 				else
 					if (m_nMinFilter >= FILTER_ANISO2X && m_nMagFilter >= FILTER_ANISO2X && m_nMipFilter >= FILTER_ANISO2X)
 					{
 						Desc.Filter = D3D11_FILTER_COMPARISON_ANISOTROPIC;
 						Desc.MaxAnisotropy = m_nAnisotropy;
 					}
 	}
 	else
 	{
 		if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && m_nMipFilter == FILTER_LINEAR || m_nMinFilter == FILTER_TRILINEAR || m_nMagFilter == FILTER_TRILINEAR)
 		{
 			Desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
 		}
 		else
 			if (m_nMinFilter == FILTER_LINEAR && m_nMagFilter == FILTER_LINEAR && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT) || m_nMinFilter == FILTER_BILINEAR || m_nMagFilter == FILTER_BILINEAR)
 				Desc.Filter = D3D11_FILTER_MIN_MAG_LINEAR_MIP_POINT;
 			else
 				if (m_nMinFilter == FILTER_POINT && m_nMagFilter == FILTER_POINT && (m_nMipFilter == FILTER_NONE || m_nMipFilter == FILTER_POINT))
 					Desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
 				else
 					if (m_nMinFilter >= FILTER_ANISO2X && m_nMagFilter >= FILTER_ANISO2X && m_nMipFilter >= FILTER_ANISO2X)
 					{
 						Desc.Filter = D3D11_FILTER_ANISOTROPIC;
 						Desc.MaxAnisotropy = m_nAnisotropy;
 					}
 					else
 						assert(0);
 	}
 	HRESULT hr = gcpRendD3D->m_pd3dDevice->CreateSamplerState(&Desc, &pSamp);
 	if (SUCCEEDED(hr))
 		m_pDeviceState = pSamp;
 	else
 		assert(0);
 #endif
 }
 
 STexState::~STexState()
 {
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		SAFE_RELEASE(pSamp);
 		m_pDeviceState = NULL;
 	}
 #endif
 }
 
 STexState::STexState(const STexState& src)
 {
 	memcpy(this, &src, sizeof(src));
 #if defined (DIRECT3D10)
 	if (m_pDeviceState)
 	{
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)m_pDeviceState;
 		pSamp->AddRef();
 	}
 #endif
 }
 
 bool CTexture::SetClampingMode(int nAddressU, int nAddressV, int nAddressW)
 {
 	return s_sDefState.SetClampMode(nAddressU, nAddressV, nAddressW);
 }
 
 bool CTexture::SetFilterMode(int nFilter)
 {
 	return s_sDefState.SetFilterMode(nFilter);
 }
 
 void CTexture::UpdateTexStates() 
 { 
 	m_nDefState = CTexture::GetTexState(s_sDefState); 
 }
 
 bool CTexture::SetDefTexFilter(const char *szFilter)
 {
 	uint32 i;
 	bool bRes = false;
 	struct textype
 	{
 		char *name;
 		uint32 filter;
 	};
 
 	static textype tt[] =
 	{
 		{"NEAREST", FILTER_POINT},
 		{"LINEAR", FILTER_LINEAR},
 		{"BILINEAR", FILTER_BILINEAR},
 		{"TRILINEAR", FILTER_TRILINEAR},
 	};
 
 	s_sGlobalDefState.m_nAnisotropy = CLAMP(CRenderer::CV_r_texture_anisotropic_level, 1, gcpRendD3D->m_MaxAnisotropyLevel);
 	if (!(gcpRendD3D->GetFeatures() & RFT_ALLOWANISOTROPIC))
 		s_sGlobalDefState.m_nAnisotropy = 1;
 	_SetVar("r_Texture_Anisotropic_Level", s_sGlobalDefState.m_nAnisotropy);
 	s_GlobalTextureFilter = szFilter;
 	if ((gcpRendD3D->GetFeatures() & RFT_ALLOWANISOTROPIC) && s_sDefState.m_nAnisotropy > 1)
 		szFilter = "TRILINEAR";
 
 	s_sGlobalDefState.SetClampMode(TADDR_WRAP, TADDR_WRAP, TADDR_WRAP);
 
 	if (s_sGlobalDefState.m_nAnisotropy > 1)
 	{
 		if (s_sGlobalDefState.m_nAnisotropy == 2)
 			s_sGlobalDefState.SetFilterMode(FILTER_ANISO2X);
 		else
 			if (s_sGlobalDefState.m_nAnisotropy == 4)
 				s_sGlobalDefState.SetFilterMode(FILTER_ANISO4X);
 			else
 				if (s_sGlobalDefState.m_nAnisotropy == 8)
 					s_sGlobalDefState.SetFilterMode(FILTER_ANISO8X);
 				else
 					if (s_sGlobalDefState.m_nAnisotropy == 16)
 						s_sGlobalDefState.SetFilterMode(FILTER_ANISO16X);
 					else
 					{
 						assert(0);
 						s_sGlobalDefState.m_nAnisotropy = 2;
 						s_sGlobalDefState.SetFilterMode(FILTER_ANISO2X);
 					}
 					bRes = true;
 	}
 	else
 	{
 		for (i=0; i<4; i++)
 		{
 			if (!stricmp(szFilter, tt[i].name) )
 			{
 				s_sGlobalDefState.SetFilterMode(tt[i].filter);
 				bRes = true;
 				break;
 			}
 		}
 	}
 	s_nGlobalDefState = CTexture::GetTexState(s_sGlobalDefState);
 	if (bRes)
 	{
 		SResourceContainer *pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
 		if (pRL)
 		{
 			ResourcesMapItor itor;
 			for (itor=pRL->m_RMap.begin(); itor!=pRL->m_RMap.end(); itor++)
 			{
 				CTexture *tx = (CTexture *)itor->second;
 				if (!tx)
 					continue;
 				tx->SetTexStates();
 			}
 		}
 		return true;
 	}
 
 	assert(0);
 	Warning("Bad texture filter name <%s>\n", szFilter);
 	return false;
 }
 
 void CTexture::SetSamplerState(int nTUnit, int nTS, int nSUnit, int nVtxTexOffSet, EHWShaderClass eHWSC)
 {  
 	FUNCTION_PROFILER_RENDER_FLAT
 	assert(gcpRendD3D->m_pRT->IsRenderThread());
 	STexStageInfo* const __restrict TexStages = s_TexStages;
 
 #if defined (DIRECT3D9)
 
 	if (CRenderer::CV_r_texnoaniso)
 	{
 		STexState *pTS = &s_TexStates[nTS];
 		if (pTS->m_nAnisotropy > 1)
 		{
 			STexState TS = *pTS;
 			TS.SetFilterMode(FILTER_BILINEAR);
 			TS.PostCreate();
 			nTS = CTexture::GetTexState(TS);
 		}
 	}
 
 #if !defined(XENON)
 	{
 		LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();   
 		bool sRGBRead = gRenDev->IsLinearSpaceShadingEnabled() && ( m_bIsSRGB || s_TexStates[nTS].m_bSRGBLookup && (m_nFlags& FT_USAGE_ALLOWREADSRGB));    
 		STexState *pDTS = &TexStages[nTUnit].m_State;
 		if (pDTS->m_bSRGBLookup != sRGBRead )
 		{
 		  pDTS->m_bSRGBLookup = sRGBRead;
 		  dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_SRGBTEXTURE, sRGBRead ? TRUE : FALSE);
 		}
 	}
 #endif
 
 	LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();
 	if (TexStages[nTUnit].m_nCurState != nTS)
 	{
 		TexStages[nTUnit].m_nCurState = nTS;
 		STexState *pTS = &s_TexStates[nTS];
 		STexState *pDTS = &TexStages[nTUnit].m_State;
 		if(pTS->m_nMipFilter!=pDTS->m_nMipFilter)
 		{
 			pDTS->m_nMipFilter = pTS->m_nMipFilter;
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MIPFILTER, pTS->m_nMipFilter);            
 		}
 		if(pTS->m_nMinFilter!=pDTS->m_nMinFilter || pTS->m_nMagFilter!=pDTS->m_nMagFilter || pTS->m_nAnisotropy!=pDTS->m_nAnisotropy)
 		{
 			pDTS->m_nMinFilter = pTS->m_nMinFilter;
 			pDTS->m_nMagFilter = pTS->m_nMagFilter;
 			pDTS->m_nAnisotropy = pTS->m_nAnisotropy;
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MINFILTER, pTS->m_nMinFilter);
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MAGFILTER, pTS->m_nMagFilter);
 			if (pTS->m_nMinFilter == D3DTEXF_ANISOTROPIC)
 				dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MAXANISOTROPY, pTS->m_nAnisotropy);
 		}
 		if (pTS->m_nAddressU != pDTS->m_nAddressU)
 		{
 			pDTS->m_nAddressU = pTS->m_nAddressU;
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_ADDRESSU, pTS->m_nAddressU);
 		}
 		if (pTS->m_nAddressV != pDTS->m_nAddressV)
 		{
 			pDTS->m_nAddressV = pTS->m_nAddressV;
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_ADDRESSV, pTS->m_nAddressV);
 		}
 		if (pTS->m_dwBorderColor != pDTS->m_dwBorderColor)
 		{
 			pDTS->m_dwBorderColor = pTS->m_dwBorderColor;
 
 
 
 
 
 
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_BORDERCOLOR, pTS->m_dwBorderColor);
 
 		}
 		if ((m_eTT == eTT_Cube || m_eTT == eTT_3D) && pTS->m_nAddressW != pDTS->m_nAddressW)
 		{
 			pDTS->m_nAddressW = pTS->m_nAddressW;
 			dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_ADDRESSW, pTS->m_nAddressW);
 		}
 	}
 
 	// this is quite slow on x360/ps3 (fcmp's)
 	//const float fCurrentMipBias = IsStreamed() && CRenderer::CV_r_texturesstreamingmipfading ? max(-1.f, m_fCurrentMipBias) : 0.f;	
 	////if(TexStages[nTUnit].m_fMipBias != fCurrentMipBias)
 	//{
 	//	dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&fCurrentMipBias);
 	//TexStages[nTUnit].m_fMipBias = fCurrentMipBias;
 	//}
 
 	const DWORD fCurrentMipBias = (-static_cast<int32>(IsStreamed())) & *(DWORD*)&m_fCurrentMipBias;
 	if(*(DWORD*)&TexStages[nTUnit].m_fMipBias != fCurrentMipBias)
 	{
 		dv->SetSamplerState(nTUnit + nVtxTexOffSet, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&fCurrentMipBias);
 		*(DWORD*)&TexStages[nTUnit].m_fMipBias = fCurrentMipBias;
 	}
 
 #elif defined (DIRECT3D10)
 
 
 
 
 
 
 
 
 
 	if (s_TexStateIDs[eHWSC][nSUnit] != nTS)
 
 	{
 		s_TexStateIDs[eHWSC][nSUnit] = nTS;
 
 
 
 
 
 		STexState *pTS = &s_TexStates[nTS];
 		ID3D11SamplerState *pSamp = (ID3D11SamplerState *)pTS->m_pDeviceState;
 
 		assert(pSamp);
 		if (pSamp)
 		{
 			if(!m_bVertexTexture)
       {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
         if (eHWSC == eHWSC_Pixel)
 				  gcpRendD3D->GetDeviceContext()->PSSetSamplers(nSUnit, 1, &pSamp);
         else
         if (eHWSC == eHWSC_Domain)
 				  gcpRendD3D->GetDeviceContext()->DSSetSamplers(nSUnit, 1, &pSamp);
         else
         if (eHWSC == eHWSC_Vertex)
 				  gcpRendD3D->GetDeviceContext()->VSSetSamplers(nSUnit, 1, &pSamp);
         else
           assert(0);
 
       }
 			else
 				gcpRendD3D->GetDeviceContext()->VSSetSamplers(nSUnit, 1, &pSamp);
 		}
 
 	}
 #endif
 }
 
 void CTexture::Apply(int nTUnit, int nState, int nTexMatSlot, int nSUnit, int nResView, EHWShaderClass eHWSC)
 {
 	FUNCTION_PROFILER_RENDER_FLAT
 	static int sRecursion = 0;
 #if !defined(_RELEASE)
 	if (!sRecursion)
 	{
 		/*if (this != s_ptexNoTexture)
 		{
 		s_ptexNoTexture->Apply(nTUnit, pTS, nTexMatSlot, bSRGB);
 		return;
 		}*/
 		int nT = nTexMatSlot;
 		if (nT < 0)
 			nT = 0;
 		if (CRenderer::CV_r_texgrid==nT+1 && !(m_nFlags & (FT_DONT_RELEASE | FT_USAGE_DYNAMIC | FT_USAGE_RENDERTARGET | FT_TEX_FONT)) && m_eTT == eTT_2D)
 		{
 			sRecursion++;
 			CTexture::SetGridTexture(nTUnit, this, nTexMatSlot);
 			sRecursion--;
 			return;
 		}
 		else
 			if (CRenderer::CV_r_texbindmode>=1)
 			{
 				if (CRenderer::CV_r_texbindmode==1 && !(m_nFlags & FT_TEX_FONT))
 				{
 					sRecursion++;
 					CTexture::s_ptexNoTexture->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==3 && (m_nFlags & FT_FROMIMAGE) && !(m_nFlags & FT_DONT_RELEASE))
 				{
 					sRecursion++;
 					//if (m_Flags & FT_TEX_NORMAL_MAP)
 					//  CTexture::SetGridTexture(this);
 					//else
 					CTexture::s_ptexGray->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==4 && (m_nFlags & FT_FROMIMAGE) && !(m_nFlags & FT_DONT_RELEASE) && m_eTT == eTT_2D)
 				{
 					sRecursion++;
 					CTexture::s_ptexGray->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==5 && (m_nFlags & FT_FROMIMAGE) && !(m_nFlags & FT_DONT_RELEASE) && (m_nFlags & FT_TEX_NORMAL_MAP))
 				{
 					sRecursion++;
 					CTexture::s_ptexFlatBump->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==6 && nTexMatSlot==EFTT_DIFFUSE)
 				{
 					sRecursion++;
 					CTexture::s_ptexWhite->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==7 && nTexMatSlot==EFTT_DIFFUSE)
 				{
 					sRecursion++;
 					CTexture::s_ptexMipMapDebug->Apply(nTUnit);
 					sRecursion--;
 					return;
 				}
 				else if (CRenderer::CV_r_texbindmode==8 && nTexMatSlot==EFTT_DIFFUSE)
 				{
 					assert(IsStreamed());
 					sRecursion++;
 					Apply(nTUnit);
 					if(m_pFileTexMips)
 					{
 						switch (m_nMinMipVidUploaded)
 						{
 						case 0:
 							CTexture::s_ptexColorGreen->Apply(nTUnit);
 							break;
 						case 1:
 							CTexture::s_ptexColorCyan->Apply(nTUnit);
 							break;
 						case 2:
 							CTexture::s_ptexColorBlue->Apply(nTUnit);
 							break;
 						case 3:
 							CTexture::s_ptexColorPurple->Apply(nTUnit);
 							break;
 						case 4:
 							CTexture::s_ptexColorMagenta->Apply(nTUnit);
 							break;
 						case 5:
 							CTexture::s_ptexColorYellow->Apply(nTUnit);
 							break;
 						case 6:
 							CTexture::s_ptexColorOrange->Apply(nTUnit);
 							break;
 						case 7:
 							CTexture::s_ptexColorRed->Apply(nTUnit);
 							break;
 						default:
 							CTexture::s_ptexColorWhite->Apply(nTUnit);
 							break;
 						}
 					}
 					sRecursion--;
 					return;
 				}
 				else
         if (CRenderer::CV_r_texbindmode==9 && nTexMatSlot==EFTT_DIFFUSE)
 				{
 					sRecursion++;
 					Apply(nTUnit);
 					if (m_bStreamingInProgress && m_pFileTexMips)
 					{
 						assert(IsStreamed());
 						if(m_nMinMipVidUploaded < m_pFileTexMips->m_nMinMipCur)
 						{
 							CTexture::s_ptexColorRed->Apply(nTUnit);
 						}
 						else if(m_nMinMipVidUploaded > m_pFileTexMips->m_nMinMipCur)
 						{
 							CTexture::s_ptexColorGreen->Apply(nTUnit);
 						}
 					}
 					sRecursion--;
 					return;
 				}
 				else
 				if (CRenderer::CV_r_texbindmode==10 && nTexMatSlot==EFTT_DIFFUSE)
 				{
 					sRecursion++;
 					Apply(nTUnit);
 					if (m_pFileTexMips)
 					{
 						if(m_pFileTexMips->m_nMinMipCurSigned < -2)
 						{
 							CTexture::s_ptexColorRed->Apply(nTUnit);
 						}
 						else if(m_pFileTexMips->m_nMinMipCurSigned < -1)
 						{
 							CTexture::s_ptexColorYellow->Apply(nTUnit);
 						}
 						else if(m_pFileTexMips->m_nMinMipCurSigned < 0)
 						{
 							CTexture::s_ptexColorGreen->Apply(nTUnit);
 						}
 					}
 					sRecursion--;
 					return;
 				}
 			}
 	}
 #endif
 
   assert(nTUnit >= 0);
 
 	uint32 nTSSel = Isel32(nState, m_nDefState);
 	assert(nTSSel >= 0 && nTSSel < s_TexStates.size());
 
 	int nVtxTexOffSet = 0;
 #if defined (DIRECT3D9)  
 	nVtxTexOffSet = (-static_cast<int32>(m_bVertexTexture)) & D3DVERTEXTEXTURESAMPLER0;
 #endif
 	STexStageInfo *TexStages = s_TexStages;
 
 
 
 
 
 
 
 
 	// avoiding L2 cache misses from usage from up ahead
 	PrefetchLine(m_pDevTexture, 0);
 
 	nSUnit = Isel32(nSUnit, nTUnit);
 	assert(nTUnit >= 0 && nTUnit < gcpRendD3D->m_numtmus);
 
 	CD3D9Renderer *const __restrict rd = gcpRendD3D;
 	const int nFrameID = rd->m_RP.m_TI[rd->m_RP.m_nProcessThreadID].m_nFrameUpdateID;
 
 	if (IsStreamed() && !m_bPostponed)
 	{
 		assert(m_pFileTexMips);
 		if (IsUnloaded() || !m_bStreamPrepared || IsPartiallyLoaded())
 		{
 			PROFILE_FRAME(Texture_Precache);
 			if (!CRenderer::CV_r_texturesstreaming || !m_bStreamPrepared)
 				Load(m_eTFDst);
 		}
 		static const int8 nPriorities[EFTT_MAX] = 
 		{
 				4,		//EFTT_DIFFUSE = 0,
 				2,		//EFTT_BUMP, 
 				1,		//EFTT_GLOSS,
 				0,		//EFTT_ENV,
 				3,		//EFTT_DETAIL_OVERLAY,
 				2,		//EFTT_BUMP_DIFFUSE,
 				2,		//EFTT_BUMP_HEIGHT,
 				3,		//EFTT_DECAL_OVERLAY,
 				3,		//EFTT_SUBSURFACE,
 				4,		//EFTT_CUSTOM,
 				2,		//EFTT_CUSTOM_SECONDARY,
 				4			//EFTT_OPACITY
 		};
 		assert(nTUnit < EFTT_MAX && nTUnit >= 0);
 		m_nStreamingPriority = max((int8)m_nStreamingPriority, nPriorities[min(EFTT_MAX-1, nTUnit)]);
 	}
 
 	if (!m_pDevTexture || !m_pDevTexture->GetBaseTexture())
 	{
 		// apply black by default
 		if (CTexture::s_ptexBlack && sRecursion == 0)
 		{
 			++sRecursion;
 			CTexture::s_ptexBlack->Apply(nTUnit, nState, nTexMatSlot, nResView);
 			--sRecursion;
 		}
 		return;
 	}
 
 	// Resolve multisampled RT to texture
   if (!m_bResolved)
 		Resolve();
   bool bStreamed = IsStreamed();
 	if (m_nAccessFrameID != nFrameID)
 	{ 
 		m_nAccessFrameID = nFrameID;
 
 #if !defined(_RELEASE)
 		rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextures++;
 		if (m_nFlags & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC))
 			rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_DynTexturesSize += m_nActualSize;
 		else
 		{
       if (bStreamed)
       {
 			  rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamVidSize += m_nActualSize;
         rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesStreamSysSize += m_nFullSize;
       }
       else
       {
 			  rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesSysMemSize += m_nFullSize;
         rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_ManagedTexturesVidMemSize += m_nFullSize;
       }
 		}
 #endif
 
 		// mip map fade in
 		if (bStreamed)
 		{
 			const float fCurrentMipBias = m_fCurrentMipBias;
 #if !defined(DIRECT3D10) || defined(PS3)
 			m_fCurrentMipBias = (float) __fsel(fabsf(fCurrentMipBias) - 0.26667f, fCurrentMipBias - 0.26667f * fCurrentMipBias, 0.f);
 #else
 			if(fabsf(fCurrentMipBias) > 0.26667f)
 			{
 				// one mip per half a second
 				m_fCurrentMipBias -= 0.26667f * fCurrentMipBias;
 #if defined(DIRECT3D10) && !defined(PS3)
 				// AntonK: supported only by DX11 feature set
 				// needs to be enabled for pure DX11 context
 				//if(m_pDevTexture->Get2DTexture())
 				//	gcpRendD3D->GetDeviceContext()->SetResourceMinLOD(m_pDevTexture->Get2DTexture(), m_fCurrentMipBias + (float)m_nMinMipVidUploaded);
 #endif
 			}
 			else if(fCurrentMipBias != 0.f)
 				m_fCurrentMipBias = 0.f;
 #endif
 		}
 	}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	{
 		SetSamplerState(nTUnit, nTSSel, nSUnit, nVtxTexOffSet, eHWSC);
 	}
 
 #if defined(DIRECT3D10)
 	ID3D11ShaderResourceView *pResView = NULL;
 
 #ifndef PS3
 	if (nResView>=0 && m_pRenderTargetData)
 	{
 		assert(nResView<5);
 		if (nResView==4) //multisample view
 		{
 			pResView = (ID3D11ShaderResourceView *)m_pRenderTargetData->m_pDeviceShaderResourceMS;
 		}
 		else
 		{
 			pResView = (ID3D11ShaderResourceView *)m_pRenderTargetData->m_pShaderResourceViews[nResView];
 		}
 	}
 	else
 #endif
 	{
 		pResView = (ID3D11ShaderResourceView *)m_pDeviceShaderResource;
 #if !defined(PS3)
 		if( gRenDev->IsLinearSpaceShadingEnabled() && m_nFlags& FT_USAGE_ALLOWREADSRGB )
 		{
 			if (s_TexStates[nTSSel].m_bSRGBLookup)
 				pResView = (ID3D11ShaderResourceView *)m_pDeviceShaderResourceSRGB; 
 		}	
 #endif
 	}
 	
 	if (this == TexStages[nTUnit].m_Texture && pResView == TexStages[nTUnit].m_pCurResView && eHWSC == TexStages[nTUnit].m_eHWSC) 
 		return;
 	TexStages[nTUnit].m_pCurResView = pResView;
   TexStages[nTUnit].m_eHWSC = eHWSC;
   #if !defined(PS3) // We allow reads from destination RT on PS3
     // in DX11 don't allow to set texture while it still bound as RT
     if (rd->m_pCurTarget[0] == this)
     {
       // fixme: this check is buggy - render targets setup is deferred until last moment might not be matching this check at all
 
       assert(rd->m_pCurTarget[0]->m_pDeviceRTV);
       rd->m_pNewTarget[0]->m_bWasSetRT = false;
       rd->m_pd3dDeviceContext->OMSetRenderTargets(1, &rd->m_pNewTarget[0]->m_pTarget, rd->m_pNewTarget[0]->m_pDepth);
     }
   #endif
 #else
 	if (this == TexStages[nTUnit].m_Texture)
 		return;
 #endif
 
 	TexStages[nTUnit].m_Texture = this;
 
 #if !defined(_RELEASE)
 	rd->m_RP.m_PS[rd->m_RP.m_nProcessThreadID].m_NumTextChanges++;
 #endif
 
 #ifdef DO_RENDERLOG
 	if (CRenderer::CV_r_log >= 3)
 	{
 		if (IsNoTexture())
 			rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\" (Not found)\n", nTUnit, m_SrcName.c_str());
 		else
 			rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): (%d) \"%s\"\n", nTUnit, m_SrcName.c_str());
 	}
 #endif
 
 #if defined (DIRECT3D9)  
 	HRESULT hr = rd->GetD3DDevice()->SetTexture(nTUnit+nVtxTexOffSet, m_pDevTexture->Get2DTexture());
 	assert(SUCCEEDED(hr));
 #elif defined (DIRECT3D10)
 	if (m_pDevTexture)
 	{
 #ifdef DO_RENDERLOG
 		if (CRenderer::CV_r_log >= 3 && nResView>=0)
 		{
 			rd->Logv(SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID], "CTexture::Apply(): Shader Resource View: %d \n", nResView);
 		}
 #endif
 
 		//assert(pRes);
 		if ( pResView )
 		{
 			if( !m_bVertexTexture  )
       {
         if (eHWSC == eHWSC_Pixel)
 				  rd->GetDeviceContext()->PSSetShaderResources(nTUnit, 1, &pResView);
         else
         if (eHWSC == eHWSC_Vertex)
 				  rd->GetDeviceContext()->VSSetShaderResources(nTUnit, 1, &pResView);
 #if !defined(PS3) && !defined(CAFE)
 				else
         if (eHWSC == eHWSC_Domain)
 				  rd->GetDeviceContext()->DSSetShaderResources(nTUnit, 1, &pResView);
 #endif
 				else
           assert(0);
       }
 			else
 				rd->GetDeviceContext()->VSSetShaderResources(nTUnit, 1, &pResView);
 		}
 	}
 #endif
 }
 
 void CTexture::UpdateTextureRegion(byte *data, int nX, int nY, int USize, int VSize, ETEX_Format eTFSrc)
 {
 	gRenDev->m_pRT->RC_UpdateTextureRegion(this, data, nX, nY, USize, VSize, eTFSrc);
 }
 
 void CTexture::RT_UpdateTextureRegion(byte *data, int nX, int nY, int USize, int VSize, ETEX_Format eTFSrc)
 {
 	PROFILE_FRAME(UpdateTextureRegion);
 
 	if(m_eTT != eTT_2D)
 	{
 		assert(0);
 		return;
 	}
 
 #if defined (DIRECT3D9)
 
 	CDeviceTexture *pDevTexture = NULL;
 	D3DSurface *pDestSurf = NULL;
 	pDevTexture = GetDevTexture();
 	assert(pDevTexture);
 	if (!pDevTexture)
 		return;
 
 	D3DFormat frmtSrc = CTexture::DeviceFormatFromTexFormat(eTFSrc);
 	bool bDone = false;
 	RECT rc = {nX, nY, nX+USize, nY+VSize};
 	if (m_eTT == eTT_2D)
 	{
 		if (!IsDXTCompressed(m_eTFDst))
 		{
 			int nBPPSrc = CTexture::BitsPerPixel(eTFSrc);
 			int nBPPDst = CTexture::BitsPerPixel(m_eTFDst);
 			if (nBPPSrc == nBPPDst)
 			{
 				IDirect3DSurface9 *pSurf = GetSurface(0, 0);
 
 				assert(pSurf);
 
 				D3DLOCKED_RECT lr;
 
 
 
 
 
 
 
 
 
 
 
 #if defined(DIRECT3D9) && (defined(WIN32) || defined(WIN64))
 				if (pSurf)
 #endif
 				{
 					if(pSurf->LockRect(&lr, &rc, 0)==D3D_OK)
 					{
 						byte * p = (byte*)lr.pBits;
 						int nOffsSrc = 0;
 						int nSizeLine = CTexture::TextureDataSize(USize, 1, 1, 1, eTFSrc);
 						for(int y=0; y<VSize; y++)
 						{
 							cryMemcpy(&p[y*lr.Pitch], &data[nOffsSrc], nSizeLine);
 							nOffsSrc += nSizeLine;
 						}
 						pSurf->UnlockRect();
 					}
 				}
 
 				SAFE_RELEASE(pSurf);
 				bDone = true;
 			}
 			else
       if ((eTFSrc==eTF_A8R8G8B8 || eTFSrc==eTF_X8R8G8B8) && (m_eTFDst==eTF_R5G6B5))
 			{
 				IDirect3DSurface9 *pSurf = GetSurface(0, 0);
 				D3DLOCKED_RECT lr;
 				if (pSurf->LockRect(&lr, &rc, 0)==D3D_OK)
 				{
 					byte *pBits = (byte *)lr.pBits;
 					int nOffsSrc = 0;
 					int nSizeLine = CTexture::TextureDataSize(USize, 1, 1, 1, eTFSrc);
 					for (int i=0; i<VSize; i++)
 					{
 						uint32 *src = (uint32 *)&data[nOffsSrc];
 						uint16 *dst = (uint16 *)&pBits[i*lr.Pitch];
 						for (int j=0; j<USize; j++)
 						{
 							uint32 argb = *src++;
 							*dst++ =  ((argb >> 8) & 0xF800) |
 								((argb >> 5) & 0x07E0) |
 								((argb >> 3) & 0x001F);
 						}
 						nOffsSrc += nSizeLine;
 					}
 					pSurf->UnlockRect();
 				}
 				SAFE_RELEASE(pSurf);
 				bDone = true;
 			}
 		}
 	}
 
 	// It looks stupid, but (!bDone) DOESNT work on XENON! The compiler just remove this branch
 	if (bDone)
 	{
 	}
 	else
 	{
 #ifndef XENON
 		int nPitch;
 		if (IsDXTCompressed(eTFSrc))
 		{
 			int blockSize = (eTFSrc == eTF_DXT1 || eTFSrc == eTF_CTX1) ? 8 : 16;
 			nPitch = (USize+3)/4 * blockSize;
 		}
 		else
 		{
 			int size = TextureDataSize(USize, VSize, 1, 1, eTFSrc);
 			nPitch = size / VSize;
 		}
 		RECT rcs;
 		rcs.left = 0;
 		rcs.right = USize;
 		rcs.top = 0;
 		rcs.bottom = VSize;
 		HRESULT hr;
 		pDestSurf = GetSurface(0, 0);
 		assert(pDestSurf);
 		if (pDestSurf)
 		{
 			hr = D3DXLoadSurfaceFromMemory(pDestSurf, NULL, &rc, data, frmtSrc, nPitch, NULL, &rcs, D3DX_FILTER_NONE, 0);
 			assert(SUCCEEDED(hr));
 		}
 		SAFE_RELEASE(pDestSurf);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #endif
 	}
 #elif defined (DIRECT3D10)
 	HRESULT hr = S_OK;
 	CDeviceTexture* pDevTexture = GetDevTexture();
 	assert(pDevTexture);
 	if (!pDevTexture)
 		return;
 
 	DXGI_FORMAT frmtSrc = (DXGI_FORMAT)CTexture::DeviceFormatFromTexFormat(eTFSrc);
 	bool bDone = false;
 	D3D11_BOX rc = {nX, nY, 0, nX+USize, nY+VSize, 1};
 	if (m_eTT == eTT_2D)
 	{
 		if (!IsDXTCompressed(m_eTFDst))
 		{
 			int nBPPSrc = CTexture::BitsPerPixel(eTFSrc);
 			int nBPPDst = CTexture::BitsPerPixel(m_eTFDst);
 			if(nBPPSrc == nBPPDst)
 			{
 				int nRowPitch = CTexture::TextureDataSize(USize, 1, 1, 1, eTFSrc);
 				gcpRendD3D->m_pd3dDeviceContext->UpdateSubresource(pDevTexture->Get2DTexture(), 0, &rc, data, nRowPitch, 0);
 				bDone = true;
 			}
 			else
 			if((eTFSrc==eTF_A8R8G8B8 || eTFSrc==eTF_X8R8G8B8) && (m_eTFDst==eTF_R5G6B5))
 			{
 				assert(0);
 				bDone = true;
 			}
 		}
 	}
 	if (!bDone)
 	{
 		D3D11_BOX box;
 		ZeroStruct(box);
 		box.right = USize;
 		box.bottom = VSize;
 		box.back = 1;
 		const int nPitch = CTexture::TextureDataSize(USize, 1, 1, 1, eTFSrc);
 		gcpRendD3D->m_pd3dDeviceContext->UpdateSubresource(pDevTexture->Get2DTexture(), 0, &box, data, nPitch, 0);
 	}
 #endif
 }
 
 bool CTexture::Fill(const ColorF& color)
 {
 	if (!(m_nFlags & FT_USAGE_RENDERTARGET))
 		return false;
 
 #if defined (DIRECT3D9) && !defined(XENON)
 	gRenDev->m_pRT->RC_TextureFill(this, D3DRGBA(color.r, color.g, color.b, color.a));
 	
 	/*
 	D3DSurface *pSurf = GetSurface(0, 0);
 	if (!pSurf)
 		return false;
 	HRESULT hr = gcpRendD3D->m_pd3dDevice->ColorFill(pSurf, NULL, D3DRGBA(color.r, color.g, color.b, color.a));
 	SAFE_RELEASE(pSurf);
 	if (FAILED(hr))
 		return false;
 	*/
 
 	return true;
 #else
 	//assert(0);
 	return false;
 #endif
 }
 
 void SEnvTexture::Release()
 {
 	ReleaseDeviceObjects();
 	SAFE_DELETE(m_pTex);
 }
 
 void SEnvTexture::RT_SetMatrix()
 {
 	Matrix44A matView, matProj;
 	gRenDev->GetModelViewMatrix(matView.GetData());
 	gRenDev->GetProjectionMatrix(matProj.GetData());
 
   float fWidth = m_pTex ? (float)m_pTex->GetWidth() : 1;
   float fHeight = m_pTex ? (float)m_pTex->GetHeight() : 1;
 
 	Matrix44A matScaleBias(0.5f, 0, 0,   0,
 		0, -0.5f,    0,   0,
 		0,     0, 0.5f,   0,
 		// texel alignment - also push up y axis reflection up a bit
 		0.5f+0.5f/fWidth, 0.5f+ 1.0f/fHeight, 0.5f, 1.0f);
 
 	Matrix44A m;
 	m.Multiply(matProj, matScaleBias);
 	Matrix44A mm;
 	mm.Multiply(matView, m);
 	m_Matrix = mm;
 }
 
 byte *CTexture::LockData(int& nPitch, int nSide, int nLevel)
 {
 	CDeviceTexture *pDevTexture = GetDevTexture();
   assert(pDevTexture);
   if (!pDevTexture)
     return NULL;
 	if (m_eTT == eTT_2D)
 	{
 		STexLock lr;
 		if (pDevTexture->LockRect(nLevel, lr, 0)==S_OK)
 		{
 			nPitch = lr.Pitch;
 			return lr.pData;
 		}
 	}
 	else
 	if (m_eTT == eTT_Cube)
 	{
 		STexLock lr;
 		if (pDevTexture->LockRect(nSide, nLevel, lr, 0)==S_OK)
 		{
 			nPitch = lr.Pitch;
 			return lr.pData;
 		}
 	}
 	else
 	if (m_eTT == eTT_3D)
 	{
 		STexLockBox lr;
 		if (pDevTexture->LockBox(nLevel, lr, 0)==S_OK)
 		{
 			nPitch = lr.RowPitch;
 			return lr.pData;
 		}
 	}
 	return NULL;
 }
 
 void CTexture::UnlockData(int nSide, int nLevel)
 {
   CDeviceTexture *pDevTexture = GetDevTexture();
   assert(pDevTexture);
   if (!pDevTexture)
     return;
 	if (m_eTT == eTT_2D)
 		pDevTexture->UnlockRect(nLevel);
 	else
   if (m_eTT == eTT_Cube)
 	  pDevTexture->UnlockRect(nSide, nLevel);
   else
   if (m_eTT == eTT_3D)
     pDevTexture->UnlockBox(nLevel);
 }
 
 void SEnvTexture::ReleaseDeviceObjects()
 {
 	//if (m_pTex)
 	//  m_pTex->ReleaseDynamicRT(true);
 }
 
 bool CTexture::RenderEnvironmentCMHDR(int size, Vec3& Pos, TArray<unsigned short>& vecData)
 {
 #if !defined(XENON) && !defined(PS3)
 
 	iLog->Log("Start generating a cubemap...");
 
 	vecData.SetUse(0);
 
 	int vX, vY, vWidth, vHeight;
 	gRenDev->GetViewport(&vX, &vY, &vWidth, &vHeight);
 
 	const int nOldWidth = gRenDev->GetWidth();
 	const int nOldHeight = gRenDev->GetHeight();
 	bool	bFullScreen = (iConsole->GetCVar("r_Fullscreen")->GetIVal()!=0)&&(!gEnv->IsEditor());
 	gRenDev->ChangeViewport(0, 0, size, size);
 
 	static const ColorF black(Col_Black);
 	int nPFlags = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags;
 	
 	CTexture *ptexGenEnvironmentCM = CTexture::Create2DTexture("$GenEnvironmentCM",size,size,0,FT_DONT_STREAM | FT_DONT_RESIZE | FT_USAGE_READBACK,0,eTF_A16B16G16R16F,eTF_A16B16G16R16F);
 	if( !ptexGenEnvironmentCM->GetDevTexture() ) 
 	{		
 		iLog->Log("Failed generating a cubemap: out of video memory");
 		gRenDev->ChangeViewport(0, 0, nOldWidth, nOldHeight);
 		
 		SAFE_RELEASE(ptexGenEnvironmentCM);
 		return false;
 	}
 
 	// Disable/set cvars that can affect cube map generation. This is thread unsafe (we assume editor will not run in mt mode), no other way around at this time
 	//	- coverage buffer unreliable for multiple views
 	//	- custom view distance ratios
 
 	ICVar *pCoverageBufferCV = gEnv->pConsole->GetCVar("e_CoverageBuffer");
 	const int32 nCoverageBuffer = pCoverageBufferCV? pCoverageBufferCV->GetIVal() : 0;
 	if( pCoverageBufferCV )
 		pCoverageBufferCV->Set( 0 );
 
 	ICVar *pStatObjBufferRenderTasksCV = gEnv->pConsole->GetCVar("e_StatObjBufferRenderTasks");
 	const int32 nStatObjBufferRenderTasks = pStatObjBufferRenderTasksCV? pStatObjBufferRenderTasksCV->GetIVal() : 0;
 	if( pStatObjBufferRenderTasksCV )
 		pStatObjBufferRenderTasksCV->Set( 0 );
 
 	ICVar *pViewDistRatioCV = gEnv->pConsole->GetCVar("e_ViewDistRatio");
 	const float fOldViewDistRatio = pViewDistRatioCV ? pViewDistRatioCV->GetFVal() : 1.f;
 	if( pViewDistRatioCV )
 		pViewDistRatioCV->Set( 10000.f );
 
 	ICVar *pViewDistRatioVegetationCV = gEnv->pConsole->GetCVar("e_ViewDistRatioVegetation");
 	const float fOldViewDistRatioVegetation = pViewDistRatioVegetationCV ? pViewDistRatioVegetationCV->GetFVal() : 100.f;
 	if( pViewDistRatioVegetationCV )
 		pViewDistRatioVegetationCV->Set( 10000.f );
 
 	ICVar *pLodRatioCV = gEnv->pConsole->GetCVar("e_LodRatio");
 	const float fOldLodRatio = pLodRatioCV ? pLodRatioCV->GetFVal() : 1.f;
 	if( pLodRatioCV )
 		pLodRatioCV->Set( 1000.f );
 
 	const int32 nFlaresCV = CRenderer::CV_r_flares;
 	CRenderer::CV_r_flares = 0;
 	const int32 nCoronasCV = CRenderer::CV_r_coronas;
 	CRenderer::CV_r_coronas = 0;
 
 	gcpRendD3D->EnableSwapBuffers(false);
 	for(int nSide=0; nSide<6; nSide++)
 	{ 				
 		gcpRendD3D->BeginFrame();
 		gcpRendD3D->SetViewport(0, 0, size, size);
 		
 		gcpRendD3D->SetWidth(size);
 		gcpRendD3D->SetHeight(size);
 
 		gcpRendD3D->EF_ClearBuffers(FRT_CLEAR, &black);
 
 		DrawSceneToCubeSide(Pos, size, nSide, -1);
 
 		// Transfer to sysmem
 #if defined (DIRECT3D9) && !defined(XENON)
 		D3DSurface *pSrcSurf = CTexture::s_ptexHDRTarget->GetSurface(0, 0);
 		D3DSurface *pDstSurf = ptexGenEnvironmentCM->GetSurface(0, 0);
 		gcpRendD3D->m_pd3dDevice->GetRenderTargetData(pSrcSurf, pDstSurf);
 
 		SAFE_RELEASE( pSrcSurf );
 		SAFE_RELEASE( pDstSurf );
 #elif defined( DIRECT3D10 )
 		D3D11_BOX srcBox;
 		srcBox.left = 0; srcBox.right = size;
 		srcBox.top = 0; srcBox.bottom = size;
 		srcBox.front = 0; srcBox.back = 1;
 
 		CDeviceTexture *pDevTextureSrc = CTexture::s_ptexHDRTarget->GetDevTexture();		
 		CDeviceTexture *pDevTextureDst = ptexGenEnvironmentCM->GetDevTexture();		
 
 		gcpRendD3D->m_pd3dDeviceContext->CopySubresourceRegion(pDevTextureDst->Get2DTexture(), 0, 0, 0, 0, pDevTextureSrc->Get2DTexture(), 0, &srcBox);
 #endif
 
 		STexLock rect;  
 		CDeviceTexture *pDstDevTex = ptexGenEnvironmentCM->GetDevTexture();
 		if (SUCCEEDED(pDstDevTex->LockRect(0, rect, LF_READ)) ) 
 		{
 			byte *pTarg = (byte *)rect.pData;
 			vecData.Copy((unsigned short *)pTarg, CTexture::TextureDataSize(size, size, 1, 1, eTF_A16B16G16R16F)/sizeof(unsigned short));
 			pDstDevTex->UnlockRect(0);
 		}
 
 			gcpRendD3D->EndFrame();
 		}
 
 	SAFE_RELEASE(ptexGenEnvironmentCM);
 
 	// Restore previous states
 
 	gRenDev->ChangeViewport(0, 0, nOldWidth, nOldHeight);
 
 	gcpRendD3D->EnableSwapBuffers(true);
 	gcpRendD3D->SetWidth(vWidth);
 	gcpRendD3D->SetHeight(vHeight);
 	gcpRendD3D->RT_SetViewport(vX, vY, vWidth, vHeight);
 	gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags = nPFlags;
 	gcpRendD3D->ResetToDefault();
 
 	if( pCoverageBufferCV )
 		pCoverageBufferCV->Set( nCoverageBuffer );
 
 	if( pStatObjBufferRenderTasksCV )
 		pStatObjBufferRenderTasksCV->Set( nStatObjBufferRenderTasks );
 
 	if( pViewDistRatioCV )
 		pViewDistRatioCV->Set( fOldViewDistRatio );
 
 	if( pViewDistRatioVegetationCV )
 		pViewDistRatioVegetationCV->Set( fOldViewDistRatioVegetation );
 
 	if( pLodRatioCV )
 		pLodRatioCV->Set( fOldLodRatio );
 
 	CRenderer::CV_r_flares = nFlaresCV;
 	CRenderer::CV_r_coronas = nCoronasCV;
 
 	iLog->Log("Successfully finished generating a cubemap");
 #endif
 
 	return true;
 }
 
 bool CTexture::ScanEnvironmentCM(const char *name, int size, Vec3& Pos)
 {
 	int RendFlags = -1;
 
   // how to skip characters only ?
 	//RendFlags &= ~DLD_ENTITIES;
 
   // hack: no way to make 3dengine skip characters for now
   ICVar *ca_DrawCharacter = gEnv->pConsole->GetCVar("ca_DrawCharacter");
   int nDrawCharacterState = 0;
   if( ca_DrawCharacter )
     nDrawCharacterState = ca_DrawCharacter->GetIVal();
 
 	int vX, vY, vWidth, vHeight;
 	gRenDev->GetViewport(&vX, &vY, &vWidth, &vHeight);
 
 #if defined (DIRECT3D9)
 
 	int n;
 	LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();
 	LPDIRECT3DCUBETEXTURE9 pID3DSysTexture = NULL;
 	D3DLOCKED_RECT d3dlrTarg, d3dlrSys;
 	HRESULT h;
 
 	//CRenderer::CV_r_log = 3;
 	//gcpRendD3D->ChangeLog();
 	LPDIRECT3DSURFACE9 pTargetSurf;
 	h = dv->CreateRenderTarget(size, size, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pTargetSurf, NULL);
 	if (FAILED(h))
 		return false;
 
 	SDynTexture *pDynT = new SDynTexture(size, size, eTF_A16B16G16R16F, eTT_2D, FT_DONT_RELEASE | FT_DONT_STREAM | FT_DONT_RESIZE, "$TempEnv");
 	pDynT->Update(size, size);
 	CTexture *tpSrc = pDynT->m_pTexture;
 
 	h = D3DXCreateCubeTexture(gcpRendD3D->GetDevice(), size, D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pID3DSysTexture);
 	if (FAILED(h))
 		return false;
 
 	int *pFR = (int *)gRenDev->EF_Query(EFQ_Pointer2FrameID);
 	I3DEngine *eng = (I3DEngine *)gEnv->p3DEngine;
 	float fMaxDist = eng->GetMaxViewDistance();
 	ColorF black(Col_Black);
 	SD3DSurface *srfDepth = gcpRendD3D->FX_GetDepthSurface(size, size, false);
 	int nPFlags = gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags;
 	//gcpRendD3D->m_RP.m_TI.m_PersFlags |= RBPF_HDR;
 
   if( ca_DrawCharacter )
     ca_DrawCharacter->Set( 0 );
 
   gcpRendD3D->EF_StartEf();
 	for(n=0; n<6; n++)
 	{ 
 		(*pFR)++;
 
 		gcpRendD3D->FX_PushRenderTarget(0, tpSrc, srfDepth);
 		//gcpRendD3D->FX_PushRenderTarget(0, pTargetSurf, gcpRendD3D->FX_GetDepthSurface(size, size, false));
 
 		gcpRendD3D->RT_SetViewport(0, 0, size, size);
 		gcpRendD3D->EF_ClearBuffers(FRT_CLEAR, &black);
 
 		gcpRendD3D->FX_Commit();
 		DrawCubeSide(Pos, size, n, RendFlags, fMaxDist);
 		gcpRendD3D->FX_PopRenderTarget(0);
 
     //tpSrc->SaveJPG("cm_debug.jpg", 0);
 
 		// Post process (blurring)
 		if (pTargetSurf)
 		{
 			STexState TexStateLinear = STexState(FILTER_LINEAR, true);
 			gcpRendD3D->FX_PushRenderTarget(0, pTargetSurf, srfDepth);
 			gcpRendD3D->SetCullMode(R_CULL_NONE);
 			gcpRendD3D->RT_SetViewport(0, 0, size, size);
 			
       tpSrc->Apply(0, CTexture::GetTexState(TexStateLinear));
 
 			static CCryNameR techName("EncodeHDR");
 
       CCryNameTSCRC techName2("Encode_ToLDR");      
 			gcpRendD3D->DrawFullScreenQuad(CShaderMan::m_shHDRPostProcess, techName2, 0, 0, 1, 1);
 			gcpRendD3D->FX_PopRenderTarget(0);
 			gcpRendD3D->FX_Commit();
 
 			// Copy data
 			h = pTargetSurf->LockRect(&d3dlrTarg, NULL, 0);
 			h = pID3DSysTexture->LockRect((D3DCUBEMAP_FACES)n, 0, &d3dlrSys, NULL, 0);
 			byte *pSys = (byte *)d3dlrSys.pBits;
 			byte *pTarg = (byte *)d3dlrTarg.pBits;
 			memcpy(pSys, pTarg, size*size*4);
 			h = pID3DSysTexture->UnlockRect((D3DCUBEMAP_FACES)n, 0);
 			h = pTargetSurf->UnlockRect();
 		}
 	}
 	SRendItem::m_RecurseLevel[gRenDev->m_RP.m_nProcessThreadID]--;
 	TArray<byte> Data;
 	h = D3DXFilterCubeTexture(pID3DSysTexture, NULL, D3DX_DEFAULT, D3DTEXF_LINEAR);
 	int nMips = CTexture::CalcNumMips(size, size);
 	for (n=0; n<6; n++)
 	{
 		int wd = size;
 		int hg = size;
 		for (int i=0; i<nMips; i++)
 		{
 			assert(wd || hg);
 			if (!wd)
 				wd = 1;
 			if (!hg)
 				hg = 1;
 			pID3DSysTexture->LockRect((D3DCUBEMAP_FACES)n, i, &d3dlrSys, NULL, 0);
 			Data.Copy((byte *)d3dlrSys.pBits, CTexture::TextureDataSize(wd, hg, 1, 1, eTF_A8R8G8B8));
 			h = pID3DSysTexture->UnlockRect((D3DCUBEMAP_FACES)n, i);
 			wd >>= 1;
 			hg >>= 1;
 		}
 	}
 
 	::WriteDDS(&Data[0], size, size, 1, name, eTF_A8R8G8B8, nMips, eTT_Cube);
 
 	gcpRendD3D->RT_SetViewport(vX, vY, vWidth, vHeight);
 	gcpRendD3D->m_RP.m_TI[gcpRendD3D->m_RP.m_nProcessThreadID].m_PersFlags = nPFlags;
 
 	SAFE_RELEASE(pTargetSurf);
 	SAFE_RELEASE(pID3DSysTexture);
 	SAFE_DELETE(pDynT);
 
 #elif defined (DIRECT3D10)
 	assert(0);
 #endif
 
   if( ca_DrawCharacter )
     ca_DrawCharacter->Set( nDrawCharacterState );
 
 	//CRenderer::CV_r_log = 0;
 	//gcpRendD3D->ChangeLog();
 
 	return true;
 }
 
 //////////////////////////////////////////////////////////////////////////
 
 void CTexture::DrawSceneToCubeSide(Vec3& Pos, int tex_size, int side, int RendFlags)
 {  
 	const float sCubeVector[6][7] = 
 	{
 		{ 1, 0, 0, 0, 0, 1,-90}, //posx
 		{-1, 0, 0, 0, 0, 1, 90}, //negx
 		{ 0,-1, 0, 0, 0, 1,  0}, //posy
 		{ 0, 1, 0, 0, 0,-1,  0}, //negy    
 		{ 0, 0, 1, 0, 1, 0,  0}, //posz 
 		{ 0, 0,-1, 0, 1, 0,  0}, //negz
 	};
 
 	if (!iSystem)
 		return;
 
 	CRenderer *r = gRenDev;
 	CCamera prevCamera = r->GetCamera();
 	CCamera tmpCamera = prevCamera;
 
 	I3DEngine *eng = gEnv->p3DEngine;
 
 	Vec3 vForward = Vec3(sCubeVector[side][0], sCubeVector[side][1], sCubeVector[side][2]);
 	Vec3 vUp      = Vec3(sCubeVector[side][3], sCubeVector[side][4], sCubeVector[side][5]);
 
 	Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[side][6]));
 
 	// magic orientation we use in engine
 	Matrix33 matScale = Matrix33::CreateScale( Vec3(1.0f, -1.0f, 1.0f) ); 
 	matRot = matScale * matRot;
 
 	Matrix34 mFinal = Matrix34(matRot, Pos); 
 	tmpCamera.SetMatrix( mFinal );
 	tmpCamera.SetFrustum(tex_size, tex_size, 90.0f*gf_PI/180.0f, prevCamera.GetNearPlane(), prevCamera.GetFarPlane()); //90.0f*gf_PI/180.0f
 
 #ifdef DO_RENDERLOG
 	if (CRenderer::CV_r_log)
 		r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. DrawSceneToCubeSide .. (DrawCubeSide %d)\n", side);
 #endif
 
 	int nPersFlags = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags;
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_MIRRORCULL;// | RBPF_MIRRORCAMERA | RBPF_DRAWTOTEXTURE;
 
 	eng->RenderWorld(SHDF_ALLOWPOSTPROCESS | SHDF_ALLOWHDR | SHDF_ZPASS | SHDF_NOASYNC | SHDF_STREAM_SYNC, &tmpCamera, 1, __FUNCTION__, RendFlags, -1);
 
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags = nPersFlags;
 
 #ifdef DO_RENDERLOG
 	if (CRenderer::CV_r_log)
 		r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. End DrawSceneToCubeSide .. (DrawCubeSide %d)\n", side);
 #endif
 
 	r->SetCamera(prevCamera);
 }
 
 //////////////////////////////////////////////////////////////////////////
 
 void CTexture::DrawCubeSide(Vec3& Pos, int tex_size, int side, int RendFlags, float fMaxDist)
 {  
 	const float sCubeVector[6][7] = 
 	{
 		{ 1, 0, 0, 0, 0, 1,-90}, //posx
 		{-1, 0, 0, 0, 0, 1, 90}, //negx
 		{ 0,-1, 0, 0, 0, 1,  0}, //posy
 		{ 0, 1, 0, 0, 0,-1,  0}, //negy    
 		{ 0, 0, 1, 0, 1, 0,  0}, //posz 
 		{ 0, 0,-1, 0, 1, 0,  0}, //negz
 	};
 
 	if (!iSystem)
 		return;
 
 	CRenderer *r = gRenDev;
 	CCamera prevCamera = r->GetCamera();
 	CCamera tmpCamera = prevCamera;
 
 	I3DEngine *eng = gEnv->p3DEngine;
 	float fMinDist = 0.25f;
 
 	Vec3 vForward = Vec3(sCubeVector[side][0], sCubeVector[side][1], sCubeVector[side][2]);
 	Vec3 vUp      = Vec3(sCubeVector[side][3], sCubeVector[side][4], sCubeVector[side][5]);
   Matrix33 matRot = Matrix33::CreateOrientation(vForward, vUp, DEG2RAD(sCubeVector[side][6]));
   
   // magic orientation we use in engine
   Matrix33 matScale = Matrix33::CreateScale( Vec3(1, -1, 1) ); 
   matRot = matScale * matRot;
    
   tmpCamera.SetMatrix( Matrix34(matRot, Pos) );
 	tmpCamera.SetFrustum(tex_size, tex_size, 90.0f*gf_PI/180.0f, fMinDist, fMaxDist);
 	int nPersFlags = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags;
 	int nPersFlags2 = r->m_RP.m_PersFlags2;
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags |= /*RBPF_MIRRORCAMERA | */ RBPF_MIRRORCULL | RBPF_DRAWTOTEXTURE | RBPF_ENCODE_HDR;
 	int nOldZ = CRenderer::CV_r_usezpass;
 	CRenderer::CV_r_usezpass = 0;
 
 	r->RT_SetViewport(0, 0, tex_size, tex_size);
 
 #ifdef DO_RENDERLOG
 	if (CRenderer::CV_r_log)
 		r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. DrawLowDetail .. (DrawCubeSide %d)\n", side);
 #endif
 
 	eng->RenderWorld(SHDF_ALLOWHDR | SHDF_NOASYNC | SHDF_STREAM_SYNC, &tmpCamera, 1, __FUNCTION__, RendFlags, -1);
 
 #ifdef DO_RENDERLOG
 	if (CRenderer::CV_r_log)
 		r->Logv(SRendItem::m_RecurseLevel[r->m_RP.m_nProcessThreadID], ".. End DrawLowDetail .. (DrawCubeSide %d)\n", side);
 #endif
 
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags = nPersFlags;
 	r->m_RP.m_PersFlags2 = nPersFlags2;
 	r->SetCamera(prevCamera);
 	CRenderer::CV_r_usezpass = nOldZ;
 }
 
 void GetSampleOffsets_DownScale4x4( uint32 dwWidth, uint32 dwHeight, Vec4 avSampleOffsets[]);
 
 static void sSceneToSceneScaled8x8(CShader *pSH, CTexture *pDstTex, int nSrcTexSize, int nSide)
 {
 	assert(nSrcTexSize == 8);
 	CD3D9Renderer *r = gcpRendD3D;
 	int nTempTexSize = nSrcTexSize >> 1;
 
 	ETEX_Format eTF = r->IsHDRModeEnabled() ? eTF_A16B16G16R16F : eTF_A8R8G8B8;
 	SDynTexture *pTempTex = new SDynTexture(nTempTexSize, nTempTexSize, eTF, eTT_2D, FT_NOMIPS, "TempEnvCMap");
 	pTempTex->Update(nTempTexSize, nTempTexSize);
 	CTexture *tpDst = pTempTex->m_pTexture;
 
 	Vec4 avSampleOffsets[16];
 	SD3DSurface *srfDepth = r->FX_GetDepthSurface(nTempTexSize, nTempTexSize, false);
 	r->FX_SetRenderTarget(0, tpDst, srfDepth);
 	r->RT_SetViewport(0, 0, nTempTexSize, nTempTexSize);
 	GetSampleOffsets_DownScale4x4(nSrcTexSize, nSrcTexSize, avSampleOffsets);
 	static CCryNameR SampleOffsetsName("SampleOffsets");
 	pSH->FXSetPSFloat(SampleOffsetsName, avSampleOffsets, 16);
 	static CCryNameTSCRC DownScale4x4_techName("DownScale4x4");
 	r->DrawFullScreenQuad(CShaderMan::m_shHDRPostProcess, DownScale4x4_techName, 0, 0, 1, 1);
 
 	r->FX_SetRenderTarget(0, pDstTex, srfDepth, false, false, nSide);
 	STexState TexStatePoint = STexState(FILTER_POINT, true);
 	tpDst->Apply(0, CTexture::GetTexState(TexStatePoint));
 	r->RT_SetViewport(0, 0, 1, 1);
 	static CCryNameTSCRC DownScale4x4_EncodeLDR_techName("DownScale4x4_EncodeLDR");
 	r->DrawFullScreenQuad(CShaderMan::m_shHDRPostProcess, DownScale4x4_EncodeLDR_techName, 0, 0, 1, 1);
 
 	SAFE_DELETE(pTempTex);
 }
 
 bool CTexture::ScanEnvironmentCube(SEnvTexture *pEnv, uint32 nRendFlags, int Size, bool bLightCube)
 {
 	if (pEnv->m_bInprogress)
 		return true;
 
 	HRESULT hr = S_OK;
 	CD3D9Renderer *r = gcpRendD3D;
 	int vX, vY, vWidth, vHeight;
 	r->GetViewport(&vX, &vY, &vWidth, &vHeight);
 	r->EF_PushFog();
 
 	int Start, End;
 	if (!pEnv->m_bReady/* || CRenderer::CV_r_envcmwrite*/)
 	{
 		Start = 0;
 		End = 6;
 	}
 	else
 	{
 		Start = pEnv->m_MaskReady;
 		End = pEnv->m_MaskReady+1;
 		//Start = 0;
 		//End = 6;
 	}
 	int nPersFlags = r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags;
 	int nPersFlags2 = r->m_RP.m_PersFlags2;
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags |= RBPF_DRAWTOTEXTURE | RBPF_ENCODE_HDR;
 
 	int nTexSize = 0;
 	int nTempTexSize = nTexSize;
 	if (bLightCube)
 	{
 		nTexSize = 1;
 		nTempTexSize = 8;
 	}
 	else
 	{
 		switch (CRenderer::CV_r_envcmresolution)
 		{
 		case 0:
 			nTexSize = 64;
 			break;
 		case 1:
 			nTexSize = 128;
 			break;
 		case 2:
 		default:
 			nTexSize = 256;
 			break;
 		case 3:
 			nTexSize = 512;
 			break;
 		}
 		nTexSize = sLimitSizeByScreenRes(nTexSize);
 		nTempTexSize = nTexSize;
 	}
 
 	int n;
 	Vec3 cur_pos;
 
 	pEnv->m_bInprogress = true;
 	pEnv->m_pTex->Update(nTexSize, nTexSize);
 	ETEX_Format eTF = r->IsHDRModeEnabled() ? eTF_A16B16G16R16F : eTF_A8R8G8B8;
 	SDynTexture *pTempTex = new SDynTexture(nTempTexSize, nTempTexSize, eTF, eTT_2D, FT_NOMIPS, "TempEnvCMap");
 	pTempTex->Update(nTempTexSize, nTempTexSize);
 	pEnv->m_TexSize = nTexSize;
 
 	CTexture *tpDst = pEnv->m_pTex->m_pTexture;
 	CTexture *tpSrc = pTempTex->m_pTexture;
 	Vec3 Pos;
 	if (r->m_RP.m_pRE)
 		r->m_RP.m_pRE->mfCenter(Pos, r->m_RP.m_pCurObject);
 	else
 		Pos = pEnv->m_ObjPos;
 	nRendFlags &= ~DLD_ENTITIES;
 
 	I3DEngine *eng = (I3DEngine *)gEnv->p3DEngine;
 	float fMaxDist = eng->GetMaxViewDistance();
 	if (bLightCube)
 		fMaxDist *= 0.25f;
 	int *pFR = (int *)r->EF_Query(EFQ_Pointer2FrameID);
 	for(n=Start; n<End; n++)
 	{ 
 		(*pFR)++;
 
 		if (bLightCube)
 		{
 			/*if (!pEnv->m_pRenderTargets[n])
 			{
 			IDirect3DSurface9* pSurface;
 			hr = r->m_pd3dDevice->CreateRenderTarget(tex_size, tex_size, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pSurface, NULL);
 			if (!FAILED(hr))
 			pEnv->m_pRenderTargets[n] = pSurface;
 			}*/
 			/*if (!pEnv->m_pQuery[n])
 			{
 			LPDIRECT3DQUERY9 pQuery;
 			hr = r->m_pd3dDevice->CreateQuery(D3DQUERYTYPE_EVENT, &pQuery);
 			pEnv->m_pQuery[n] = pQuery;
 			pQuery->Issue(D3DISSUE_END);
 			}
 			else*/
 			//if (pEnv->m_nFrameCreated[n] >= 0)
 			//  continue;
 		}
 
 		// render object
 		SD3DSurface *srfDepth = r->FX_GetDepthSurface(nTempTexSize, nTempTexSize, false);
 		bool bRes = r->FX_PushRenderTarget(0, tpSrc, srfDepth);
 		ColorF col = r->m_cClearColor;
 		col.a = 0;
 		r->EF_ClearBuffers(FRT_CLEAR, &col);
 		r->FX_Commit();
 		DrawCubeSide(Pos, nTempTexSize, n, nRendFlags, fMaxDist);
 
 		// Post process (bluring)
 		if (tpDst) // || pEnv->m_pRenderTargets[n])
 		{
 			STexState TexStatePoint = STexState(FILTER_POINT, true);
 			tpSrc->Apply(0, CTexture::GetTexState(TexStatePoint));
 
 			if (!bLightCube)
 			{
 #if defined(DIRECT3D10)
 				// COMMENT: CarstenW
 				// Can no longer bind 2d depth buffer when rendering to cube map faces. As per DX11 spec a cube map depth 
 				// buffer needs to be used (driver crashed when binding the targets in FX_Commit/FX_SetActiveRenderTargets). 
 				// For the following blitting op there's no depth buffer needed anyway so simply don't bind one to fix the 
 				// problem. Needs to be verified once auto cube map rendering is fully supported again (if ever).
 				r->FX_SetState(GS_NODEPTHTEST);
 				r->FX_SetRenderTarget(0, tpDst, 0, false, false, n);
 #else
 				r->FX_SetRenderTarget(0, tpDst, srfDepth, false, false, n);
 #endif
 				r->RT_SetViewport(0, 0, nTexSize, nTexSize);
 				static CCryNameTSCRC techName("Encode_ToLDR");
 				r->DrawFullScreenQuad(CShaderMan::m_shHDRPostProcess, techName, 0, 0, 1, 1);
 			}
 			else
 				sSceneToSceneScaled8x8(CShaderMan::m_shHDRPostProcess, tpDst, nTempTexSize, n);
 			assert(n < 6);
 			pEnv->m_nFrameCreated[n] = r->GetFrameID(false);
 		}
 		r->FX_PopRenderTarget(0);
 	}
 /*
 	if (CRenderer::CV_r_envcmwrite)
 	{
 		for(n=Start; n<End; n++)
 		{ 
 		static char* cubefaces[6] = {"posx","negx","posy","negy","posz","negz"};
 		char str[64];
 		int width = tex_size;
 		int height = tex_size;
 		byte *pic = new byte [width * height * 4];
 		LPDIRECT3DSURFACE9 pSysSurf, pTargetSurf;
 		LPDIRECT3DTEXTURE9 pID3DSysTexture;
 		D3DLOCKED_RECT d3dlrSys;
 		if (!pID3DTargetTextureCM)
 		pTargetSurf = (LPDIRECT3DSURFACE9)pEnv->m_pRenderTargets[n];
 		else
 		h = pID3DTargetTextureCM->GetCubeMapSurface((D3DCUBEMAP_FACES)n, 0, &pTargetSurf);
 		h = D3DXCreateTexture(r->GetDevice(), tex_size, tex_size, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pID3DSysTexture);
 		h = pID3DSysTexture->GetSurfaceLevel(0, &pSysSurf);
 		if (pID3DTargetTexture)
 		h = D3DXLoadSurfaceFromSurface(pSysSurf, NULL, NULL, pTargetSurf, NULL, NULL,  D3DX_FILTER_NONE, 0);
 		else
 		h = r->m_pd3dDevice->GetRenderTargetData(pTargetSurf, pSysSurf);
 		h = pID3DSysTexture->LockRect(0, &d3dlrSys, NULL, 0);
 		byte *src = (byte *)d3dlrSys.pBits;
 		for (int i=0; i<width*height; i++)
 		{
 		*(uint32 *)&pic[i*4] = *(uint32 *)&src[i*4];
 		Exchange(pic[i*4+0], pic[i*4+2]);
 		}
 		h = pID3DSysTexture->UnlockRect(0);
 		sprintf(str, "Cube_%s.jpg", cubefaces[n]);
 		WriteJPG(pic, width, height, str, 24); 
 		delete [] pic;
 		if (pID3DTargetTextureCM)
 		SAFE_RELEASE (pTargetSurf);
 		SAFE_RELEASE (pSysSurf);
 		SAFE_RELEASE (pID3DSysTexture);
 		}
 		CRenderer::CV_r_envcmwrite = 0;
 	}
 */
 	SAFE_DELETE(pTempTex);
 
 	r->RT_SetViewport(vX, vY, vWidth, vHeight);
 	pEnv->m_bInprogress = false;
 	pEnv->m_MaskReady = End;
 	if (pEnv->m_MaskReady == 6)
 	{
 		pEnv->m_MaskReady = 0;
 		pEnv->m_bReady = true;
 	}
 	r->m_RP.m_TI[r->m_RP.m_nProcessThreadID].m_PersFlags = nPersFlags;
 	r->m_RP.m_PersFlags2 = nPersFlags2;
 
 	r->EF_PopFog();
 
 	return true;
 }
 
 CTexture *CTexture::MakeSpecularTexture(float fExp)
 {
 	assert(0);
 	return NULL;
 }
 
 //================================================================================
 
 VOID CFnMap::Fill2DWrapper(D3DXVECTOR4* pOut, const D3DXVECTOR2* pTexCoord, const D3DXVECTOR2* pTexelSize, LPVOID pData)
 {
 	CFnMap* map = (CFnMap*)pData;
 
 
 
 	const D3DXCOLOR& c = map->Function(pTexCoord, pTexelSize);
 	*pOut = D3DXVECTOR4((const float*)c);
 
 }
 
 int CFnMap::Initialize()
 {
 #if defined (DIRECT3D9)
 
 	D3DTexture *pTexture;
 	HRESULT hr;
 	LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();
 
 	hr = D3DXCreateTexture(gcpRendD3D->GetDevice(), m_dwWidth, m_dwHeight, m_nLevels, 0, m_Format, TEXPOOL, &pTexture);
 	if (FAILED(hr))
 	{
 		OutputDebugString("Can't create texture\n");
 		return hr;
 	}
 
 	if (FAILED(hr=D3DXFillTexture(pTexture, Fill2DWrapper, (void*)this)))
 		return hr;
 
 	CTexture *tp = m_pTex;
   SAFE_RELEASE(tp->m_pDevTexture); 
 	tp->m_pDevTexture = new CDeviceTexture(pTexture);
   if (tp->m_pDevTexture) 
     tp->m_pDevTexture->SetNoDelete(!!(tp->m_nFlags & FT_DONT_RELEASE)); 
 	tp->m_nWidth = m_dwWidth;
 	tp->m_eTFDst = tp->m_eTFSrc = CTexture::TexFormatFromDeviceFormat(m_Format);
 	tp->m_nHeight = m_dwHeight;
 	tp->m_nMips = m_nLevels;
 	tp->m_nActualSize = CTexture::TextureDataSize(tp->m_nWidth, tp->m_nHeight, tp->m_nDepth, tp->m_nMips, tp->GetDstFormat());
 #elif defined (DIRECT3D10)
 	byte *pData[6] = {0,0,0,0,0,0};
 	CTexture *tp = m_pTex;
 	tp->m_nWidth = m_dwWidth;
 	tp->m_nHeight = m_dwHeight;
 	tp->m_nMips = m_nLevels;
 	tp->CreateDeviceTexture(pData);
 #endif
 	return S_OK;
 }
 
 VOID CFnMap3D::Fill3DWrapper(D3DXVECTOR4* pOut, const D3DXVECTOR3* pTexCoord, const D3DXVECTOR3* pTexelSize, LPVOID pData)
 {
 	CFnMap3D* map = (CFnMap3D*)pData;
 
 
 
 	const D3DXCOLOR& c = map->Function(pTexCoord, pTexelSize);
 	*pOut = D3DXVECTOR4((const float*)c);
 
 }
 
 int CFnMap3D::Initialize()
 {
 #if defined (DIRECT3D9)
 
 	LPDIRECT3DVOLUMETEXTURE9 pID3DVolTexture = NULL;
 	HRESULT hr;
 	LPDIRECT3DDEVICE9 dv = gcpRendD3D->GetD3DDevice();
 
 	hr = D3DXCreateVolumeTexture (gcpRendD3D->GetDevice(), m_dwWidth, m_dwHeight, m_dwDepth, m_nLevels, 0, m_Format, TEXPOOL, &pID3DVolTexture);
 	if (FAILED(hr))
 	{
 		OutputDebugString("Can't create texture\n");
 		return hr;
 	}
 
 	if (FAILED(hr=D3DXFillVolumeTexture(pID3DVolTexture, Fill3DWrapper, (void*)this)))
 		return hr;
 
 	CTexture *tp = m_pTex;
   SAFE_RELEASE(tp->m_pDevTexture);
 	tp->m_pDevTexture = new CDeviceTexture(pID3DVolTexture);
   if (tp->m_pDevTexture) 
     tp->m_pDevTexture->SetNoDelete(!!(tp->m_nFlags & FT_DONT_RELEASE));
 	tp->m_nWidth = m_dwWidth;
 	tp->m_nHeight = m_dwHeight;
 	tp->m_nDepth = m_dwDepth;
 	tp->m_nMips = m_nLevels;
 #elif defined (DIRECT3D10)
 	byte *pData[6] = {0,0,0,0,0,0};
 	CTexture *tp = m_pTex;
 	tp->m_nWidth = m_dwWidth;
 	tp->m_nHeight = m_dwHeight;
 	tp->m_nDepth = m_dwDepth;
 	tp->m_nMips = m_nLevels;
 	tp->CreateDeviceTexture(pData);
 #endif
 	return S_OK;
 }
 
 //=======================================================================
 
 D3DXCOLOR CMipsColorMap::Function(const D3DXVECTOR2* pTexCoord, const D3DXVECTOR2* pTexelSize)
 {
 	D3DXCOLOR vOut;
 
 	float d = 1.0f/((float)(pTexCoord->x+pTexCoord->y)/2.0f);
 	Vec3 p = Vec3(0,0,0);
 	if (d < 8)
 	{
 		p = Vec3(1,1,1);
 	}
 	else
 	{
 		float q = logf(d)/logf(2);
 		q = floorf(q+.5f);
 		if (fmodf(q,3) == 0)
 		{
 			p.x = .5;
 		}
 		if (fmodf(q,6) == 0)
 		{
 			p.x = 1;
 		}
 		if (fmodf(q,2) == 0)
 		{
 			p.y = .5;
 		}
 		if (fmodf(q,4) == 0)
 		{
 			p.y = 1;
 		}
 		q = q / m_nLevelMips;
 		p.z = q;
 	}
 
 
 
 
 
 
 	vOut.r = p.x;
 	vOut.g = p.y;
 	vOut.b = p.z;
 	vOut.a = 1;
 
 
 	return vOut;
 }
 
 CTexture *CTexture::GenerateMipsColorMap(int nWidth, int nHeight)
 {
 	CD3D9Renderer *rd = gcpRendD3D;
 	bool bMips = false;
 	ETEX_Format eTF = eTF_A8R8G8B8;
 	char str[256];
 	sprintf(str, "$MipColors_%dx%d", nWidth, nHeight);
 	CCryNameTSCRC Name = GenName(str);
 	CTexture *pTex = GetByNameCRC(Name);
 	if (pTex)
 		return pTex;
 	pTex = CTexture::CreateTextureObject(str, nWidth, nHeight, 1, eTT_2D,  FT_DONT_RELEASE, eTF);
 	CMipsColorMap *pMap = new CMipsColorMap(nWidth, nHeight, CTexture::DeviceFormatFromTexFormat(eTF), pTex, true);
 	pMap->m_nLevelMips = LogBaseTwo(nWidth);
 	pMap->m_nLevelMips = max(LogBaseTwo(nHeight), pMap->m_nLevelMips);
 	pMap->Initialize();
 	pTex->SetTexStates();
 
 	return pTex;
 }
 
 bool CTexture::GenerateMipMaps(bool bSetOrthoProj, bool bUseHW, bool bNormalMap)
 {
 	if( !(GetFlags() & FT_FORCE_MIPS) 
 		|| bSetOrthoProj || !bUseHW || bNormalMap)  //todo: implement
 		return false;
 
 #if defined( PS3 )
 
 	if( GetDevTexture() && GetDevTexture()->Get2DTexture() )
 		gcpRendD3D->m_pd3dDevice->GenerateMips( GetDevTexture()->Get2DTexture() );
 
 	return true;
 
 #endif
 
 	PROFILE_LABEL_PUSH( "GENERATE_MIPS" );
 
 	PROFILE_SHADER_START
 
 		// Get current viewport
 		int iTempX, iTempY, iWidth, iHeight;
 	gRenDev->GetViewport(&iTempX, &iTempY, &iWidth, &iHeight);
 
 	CDeviceTexture *pTex = GetDevTexture();
 	if( !pTex )
 	{
 		PROFILE_LABEL_POP( "GENERATE_MIPS" );
 		return false;   
 	}
 
 #if defined(DIRECT3D10)   
 
 	D3D11_TEXTURE2D_DESC pDesc;
 	((ID3D11Texture2D *)pTex->Get2DTexture())->GetDesc( &pDesc );
 
 	// all d3d11 devices support autogenmipmaps
 	if( m_pRenderTargetData )     
 		gcpRendD3D->GetDeviceContext()->GenerateMips((ID3D11ShaderResourceView*)m_pDeviceShaderResource );
 
 	PROFILE_LABEL_POP( "GENERATE_MIPS" );
 	return true;
 
 #elif defined (DIRECT3D9)
 
 #if !defined(XENON)	
 	if( GetPixelFormat() && GetPixelFormat()->bCanAutoGenMips)
 	{
 		pTex->Get2DTexture()->GenerateMipSubLevels();
 		PROFILE_LABEL_POP( "GENERATE_MIPS" );
 		return true;
 	}
 
 
 	// getsurface(level) -> stretch rect
 
 #endif
 
 
 	int32 nLevels = 0;
 
 
 
 
 
 
 
 	int32 nPrevMipWidth = GetWidth();
 	int32 nPrevMipHeight = GetHeight();
 	int32 nMipWidth = GetWidth();
 	int32 nMipHeight = GetHeight();
 
 	for( int32 i = 1; i < nLevels; i++ )
 	{		
 
 
 
 
 
 
 
 
 
 
 
 
 		// set view port to current mip level
 		gcpRendD3D->RT_SetViewport(0, 0, nMipWidth, nMipHeight);
 
 		static CCryNameTSCRC pTechName("TextureToTextureResampled");     
 		PostProcessUtils().ShBeginPass(CShaderMan::m_shPostEffects, pTechName, FEF_DONTSETTEXTURES | FEF_DONTSETSTATES);
 
 		gRenDev->FX_SetState(GS_NODEPTHTEST);   
 
 		// Set samples position
 		float s1 = 0.5f / (float) nPrevMipWidth;
 		float t1 = 0.5f / (float) nPrevMipHeight;       
 
 		// Use rotated grid
 		Vec4 pParams0=Vec4(-1.0f*s1, -1.0f*t1, 1.0f*s1, -1.0f*t1); 
 		Vec4 pParams1=Vec4(-1.0f*s1, 1.0f*t1, 1.0f*s1, 1.0f*t1);  
 
 		static CCryNameR pParam0Name("texToTexParams0");
 		static CCryNameR pParam1Name("texToTexParams1");
 
 		CShaderMan::m_shPostEffects->FXSetPSFloat(pParam0Name, &pParams0, 1);        
 		CShaderMan::m_shPostEffects->FXSetPSFloat(pParam1Name, &pParams1, 1); 
 
 		PostProcessUtils().SetTexture(this, 0, FILTER_LINEAR);
 
 
 
 
 
 
 
 		PostProcessUtils().DrawFullScreenQuad(nMipWidth, nMipHeight);
 
 		PostProcessUtils().ShEndPass();
 
 
 
 
 
 
 		// Set texture resolved, so that ::Apply() doesn't try to re-resolve thinking it's dirty.
 		this->SetResolved(true);
 	}
 
 
 
 
 
 
 
 
 
 
 
 
 #endif
 
 
 	gcpRendD3D->RT_SetViewport(iTempX, iTempY, iWidth, iHeight);        
 
 	gcpRendD3D->FX_Flush();
 	PROFILE_SHADER_END    
 
 	PROFILE_LABEL_POP( "GENERATE_MIPS" );
 
 	return true;
 }
 
 //==========================================================================================
 
 #define NOISE_DIMENSION 128
 #define NOISE_MIP_LEVELS 1
 
 #if !defined(LINUX)
 static double drand48(void)
 {
 	double dVal;
 	dVal=(double)cry_rand()/(double)RAND_MAX;
 
 	return dVal;
 }
 #endif
 
 void CTexture::GenerateNoiseVolumeMap()
 {
 	s_ptexNoiseVolumeMap = CTexture::ForName("Textures/Defaults/Noise3D.dds", FT_DONT_RELEASE |  FT_DONT_RESIZE | FT_DONT_STREAM, eTF_Unknown);
 }
 
 //==========================================================================================
 // Volume Map Creation: Noise vectors
 //==========================================================================================
 
 Vec3 CVectorNoiseVolMap::GetNoiseVector()
 {      
 	float alpha = ((float)drand48()) * 2.0f * 3.1415926535f;
 	float beta = ((float)drand48()) * 3.1415926535f;
 	return Vec3(cosf(alpha) * sinf(beta), sinf(alpha) * sinf(beta), cosf(beta));
 }
 
 D3DXCOLOR CVectorNoiseVolMap::Function(const D3DXVECTOR3* p, const D3DXVECTOR3* s)
 {
 	Vec3 pRandVec=GetNoiseVector();
 	pRandVec.x=pRandVec.x*0.5f+0.5f;
 	pRandVec.y=pRandVec.y*0.5f+0.5f;
 	pRandVec.z=pRandVec.z*0.5f+0.5f;
 
 	return D3DXCOLOR(pRandVec.x, pRandVec.y, pRandVec.z, 0);
 }
 
 void CTexture::GenerateVectorNoiseVolMap()
 {
 	int nVolTexSize=CVectorNoiseVolMap::m_nTexSize;
 
 	ETEX_Format eTF = eTF_X8R8G8B8;
 	if(!s_ptexVectorNoiseVolMap)
 	{
 		s_ptexVectorNoiseVolMap = CTexture::CreateTextureObject("$VectorNoiseVolume", nVolTexSize, nVolTexSize, nVolTexSize, eTT_3D,  FT_DONT_RELEASE, eTF);
 	}
 
 	CVectorNoiseVolMap *pMap = new CVectorNoiseVolMap(nVolTexSize, nVolTexSize, nVolTexSize, CTexture::DeviceFormatFromTexFormat(eTF), s_ptexVectorNoiseVolMap, 1);
 	pMap->Initialize();
 	s_ptexVectorNoiseVolMap->SetTexStates();
 }
 
 void CTexture::GenerateFlareMap()
 {
 	int i, j;
 
 	byte data[4][32][4];
 	for (i=0; i<32; i++)
 	{
 		float f = 1.0f - ((fabsf((float)i - 15.5f) - 0.5f) / 16.0f);
 		int n = (int)(f*f*255.0f);
 		for (j=0; j<4; j++)
 		{
 			byte b = n;
 			if (n < 0)
 				b = 0;
 			else
 				if (n > 255)
 					b = 255;
 			data[j][i][0] = b;
 			data[j][i][1] = b;
 			data[j][i][2] = b;
 			data[j][i][3] = 255;
 		}
 	}
 	CTexture::s_ptexFlare = CTexture::Create2DTexture("$Flare", 32, 4, 1, FT_STATE_CLAMP | FT_DONT_RELEASE, &data[0][0][0], eTF_A8R8G8B8, eTF_A8R8G8B8);
 }
 
 void CTexture::GenerateFuncTextures()
 {
 	// GenerateFlareMap();
 	// GenerateNoiseVolumeMap();
 	// GenerateNormalizationCubeMap();
 }
 
 void CTexture::DestroyZMaps()
 {
 	//SAFE_RELEASE(s_ptexZTarget);
 }
 
 void CTexture::GenerateZMaps()
 {
   int nWidth = gcpRendD3D->m_MainViewport.nWidth; //m_d3dsdBackBuffer.Width;
   int nHeight = gcpRendD3D->m_MainViewport.nHeight; //m_d3dsdBackBuffer.Height;
   ETEX_Format eTFZ = CTexture::s_eTFZ;
   uint32 nFlags =  FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_DONT_RELEASE | FT_USAGE_PREDICATED_TILING | FT_DONT_RESIZE;
 #if !defined(PS3)
   if (CRenderer::CV_r_msaa)
     nFlags |= FT_USAGE_MSAA;
   if (!s_ptexZTarget)
     s_ptexZTarget = CreateRenderTarget("$ZTarget", nWidth, nHeight, eTT_2D, nFlags, eTFZ, -1, 100);
   else
   {
     s_ptexZTarget->m_nFlags = nFlags;
     s_ptexZTarget->m_nWidth = nWidth;
     s_ptexZTarget->m_nHeight = nHeight;
     s_ptexZTarget->CreateRenderTarget(eTFZ);
   }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 #endif
 
 }
 
 void CTexture::DestroySceneMap()
 {
 	//SAFE_RELEASE(s_ptexSceneTarget);
 }
 
 void CTexture::GenerateSceneMap(ETEX_Format eTF)
 {
 	int nWidth = gcpRendD3D->GetWidth(); //m_d3dsdBackBuffer.Width;
 	int nHeight = gcpRendD3D->GetHeight(); // m_d3dsdBackBuffer.Height;
   uint32 nFlags =  FT_USAGE_PREDICATED_TILING | FT_DONT_STREAM | FT_USAGE_RENDERTARGET | FT_DONT_RESIZE;
 	nFlags |= (!CRenderer::CV_r_HDRTexFormat)? FT_CUSTOM_FORMAT : 0;
 
 	//if (CRenderer::CV_r_msaa)
 	//	nFlags |= FT_USAGE_MSAA;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
   if (!s_ptexSceneTarget)
     s_ptexSceneTarget = CreateRenderTarget("$SceneTarget", nWidth, nHeight, eTT_2D, nFlags, eTF, TO_SCENE_TARGET, 100);
   else
   {
     s_ptexSceneTarget->m_nFlags = nFlags;
     s_ptexSceneTarget->m_nWidth = nWidth;
     s_ptexSceneTarget->m_nHeight = nHeight;
     s_ptexSceneTarget->CreateRenderTarget(eTF);
   }
 
 
 
 	nFlags &= ~(FT_USAGE_MSAA|FT_CUSTOM_FORMAT);
 
 	// This RT used for all post processes passes and shadow mask (group 0) as well
 	if (!CTexture::IsTextureExist(s_ptexBackBuffer))
 		s_ptexBackBuffer = CreateRenderTarget("$BackBuffer", nWidth, nHeight, eTT_2D, nFlags, eTF_A8R8G8B8, TO_BACKBUFFERMAP, 40);
 	else
 	{
 		s_ptexBackBuffer->m_nFlags = nFlags;
 		s_ptexBackBuffer->m_nWidth = nWidth;
 		s_ptexBackBuffer->m_nHeight = nHeight;
 		s_ptexBackBuffer->CreateRenderTarget(eTF_A8R8G8B8);
 	}
 
 
 
 
 
 
 
 
 
 
 }
 
 bool SDynTexture::RT_SetRT(int nRT, int nWidth, int nHeight, bool bPush, bool bScreenVP)
 {
   Update(m_nWidth, m_nHeight);
 
   SD3DSurface *pDepthSurf = nWidth > 0 ? gcpRendD3D->FX_GetDepthSurface(nWidth, nHeight, false) : &gcpRendD3D->m_DepthBufferOrig;
 
   assert(m_pTexture);
   if (m_pTexture)
   {
     if (bPush)
       return gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf, false, -1, bScreenVP);
     else
       return gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf, false, false, -1, bScreenVP);
   }
   return false;
 }
 
 bool SDynTexture::SetRT(int nRT, bool bPush, SD3DSurface *pDepthSurf, bool bScreenVP)
 {
 	Update(m_nWidth, m_nHeight);
 
 	assert(m_pTexture);
 	if (m_pTexture)
 	{
 		if (bPush)
 			return gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf, false, -1, bScreenVP);
 		else
 			return gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf, false, false, -1, bScreenVP);
 	}
 	return false;
 }
 
 bool SDynTexture::RestoreRT(int nRT, bool bPop)
 {
 	if (bPop)
 		return gcpRendD3D->FX_PopRenderTarget(nRT);
 	else
 		return gcpRendD3D->FX_RestoreRenderTarget(nRT);
 }
 
 
 bool SDynTexture2::SetRT(int nRT, bool bPush, SD3DSurface *pDepthSurf, bool bScreenVP)
 {
 	Update(m_nWidth, m_nHeight);
 
 	assert(m_pTexture);
 	if (m_pTexture)
 	{
 		bool bRes = false;
 		if (bPush)
 			bRes = gcpRendD3D->FX_PushRenderTarget(nRT, m_pTexture, pDepthSurf);
 		else
 			bRes = gcpRendD3D->FX_SetRenderTarget(nRT, m_pTexture, pDepthSurf);
 		SetRectStates();
 		gcpRendD3D->FX_Commit();
 	}
 	return false;
 }
 
 bool SDynTexture2::SetRectStates()
 {
 	assert(m_pTexture);
 	gcpRendD3D->RT_SetViewport(m_nX, m_nY, m_nWidth, m_nHeight);
 	gcpRendD3D->EF_Scissor(true, m_nX, m_nY, m_nWidth, m_nHeight);
   RECT rc;
   rc.left = m_nX; rc.right = m_nX+m_nWidth;
   rc.top = m_nY; rc.bottom = m_nY+m_nHeight;
   if (m_pTexture)
     m_pTexture->AddDirtRect(rc, rc.left, rc.top);
 	return true;
 }
 
 bool SDynTexture2::RestoreRT(int nRT, bool bPop)
 {
 	bool bRes = false;
 	gcpRendD3D->EF_Scissor(false, m_nX, m_nY, m_nWidth, m_nHeight);
 	if (bPop)
 		bRes = gcpRendD3D->FX_PopRenderTarget(nRT);
 	else
 		bRes = gcpRendD3D->FX_RestoreRenderTarget(nRT);
 	gcpRendD3D->FX_Commit();
 
 	return bRes;
 }
 
 void _DrawText(ISystem * pSystem, int x, int y, const float fScale, const char * format, ...);
 
 static int __cdecl RTCallback(const VOID* arg1, const VOID* arg2)
 {
 	CTexture *p1 = *(CTexture **)arg1;
 	CTexture *p2 = *(CTexture **)arg2;
 
   // show big textures first
   int nSize1 = p1->GetDataSize();
   int nSize2 = p2->GetDataSize();
   if(nSize1>nSize2)
     return -1;
   else if(nSize2>nSize1)
     return 1;
 
 	return strcmp(p1->GetName(),p2->GetName());
 }
 
 void CD3D9Renderer::DrawAllDynTextures(const char *szFilter, const bool bLogNames, const bool bOnlyIfUsedThisFrame)
 {
 #ifndef _RELEASE
 	SDynTexture2::TextureSet2Itor itor;
 	char name[256]; //, nm[256];
 	strcpy_s(name, szFilter);
 	strlwr(name);
 	TArray<CTexture *> UsedRT;
 	int nMaxCount = CV_r_ShowDynTexturesMaxCount;
 
 	float width = 800;
 	float height = 600;
 	float fArrDim = max(1.f, sqrtf((float)nMaxCount));
 	float fPicDimX = width/fArrDim;
 	float fPicDimY = height/fArrDim;
 	float x = 0;
 	float y = 0;
 	Set2DMode(true, (int)width, (int)height);
 	EF_SetColorOp(eCO_MODULATE, eCO_MODULATE, DEF_TEXARG0, DEF_TEXARG0);
 	if (name[0] == '*' && !name[1])
 	{
 		SResourceContainer *pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
 		ResourcesMapItor it;
 		for (it=pRL->m_RMap.begin(); it!=pRL->m_RMap.end(); it++)
 		{
 			CTexture *tp = (CTexture *)it->second;
 			if (tp && !tp->IsNoTexture())
 			{
 				if ((tp->GetFlags() & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) && tp->GetDevTexture())
 					UsedRT.AddElem(tp);
 			}
 		}
 	}
 	else
 	{
 		SResourceContainer *pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
 		ResourcesMapItor it;
 		for (it=pRL->m_RMap.begin(); it!=pRL->m_RMap.end(); it++)
 		{
 			CTexture *tp = (CTexture *)it->second;
 			if (!tp || tp->IsNoTexture())
 				continue;
 			if ((tp->GetFlags() & (FT_USAGE_RENDERTARGET | FT_USAGE_DYNAMIC)) && tp->GetDevTexture())
 			{
 				char nameBuffer[128];
 				strncpy(nameBuffer, tp->GetName(), sizeof nameBuffer);
 				nameBuffer[sizeof nameBuffer - 1] = 0;
 				strlwr(nameBuffer);
 				if (CryStringUtils::MatchWildcard(nameBuffer, name))
 					UsedRT.AddElem(tp);
 			}
 		}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 	}
 	if (true /* szFilter[0] == '*' */)
 	{
 		if (UsedRT.Num() > 1)
 		{
 			qsort(&UsedRT[0], UsedRT.Num(), sizeof(CTexture *), RTCallback);
 		}
 	}
 	fPicDimX = width/fArrDim;
 	fPicDimY = height/fArrDim;
 	x = 0;
 	y = 0;
 	for (uint32 i=0; i<UsedRT.Num(); i++)
 	{
 		SetState(GS_NODEPTHTEST);
 		CTexture *tp = UsedRT[i];
 		int nSavedAccessFrameID = tp->m_nAccessFrameID;
 
 		if(bOnlyIfUsedThisFrame)
 			if(nSavedAccessFrameID != m_RP.m_TI[m_RP.m_nProcessThreadID].m_nFrameUpdateID)
 				continue;
 
 		if (tp->GetTextureType() == eTT_2D)
 			Draw2dImage(x, y, fPicDimX-2, fPicDimY-2, tp->GetID(), 0,1,1,0,0);
 		else
 		{
 			float fSizeX = fPicDimX / 3;
 			float fSizeY = fPicDimY / 2;
 			float fx = ScaleCoordX(x); fSizeX = ScaleCoordX(fSizeX);
 			float fy = ScaleCoordY(y); fSizeY = ScaleCoordY(fSizeY);
 			float fOffsX[] = {fx, fx+fSizeX, fx+fSizeX*2, fx, fx+fSizeX, fx+fSizeX*2};
 			float fOffsY[] = {fy, fy, fy, fy+fSizeY, fy+fSizeY, fy+fSizeY};
 			Vec3 vTC0[] = {Vec3(1,1,1), Vec3(-1,1,-1), Vec3(-1,1,-1), Vec3(-1,-1,1), Vec3(-1,1,1), Vec3(1,1,-1)};
 			Vec3 vTC1[] = {Vec3(1,1,-1), Vec3(-1,1,1), Vec3(1,1,-1), Vec3(1,-1,1), Vec3(1,1,1), Vec3(-1,1,-1)};
 			Vec3 vTC2[] = {Vec3(1,-1,-1), Vec3(-1,-1,1), Vec3(1,1,1), Vec3(1,-1,-1), Vec3(1,-1,1), Vec3(-1,-1,-1)};
 			Vec3 vTC3[] = {Vec3(1,-1,1), Vec3(-1,-1,-1), Vec3(-1,1,1), Vec3(-1,-1,-1), Vec3(-1,-1,1), Vec3(1,-1,-1)};
 
 			m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj->Push();
 			EF_PushMatrix();
 			Matrix44A *m = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj->GetTop();
 			mathMatrixOrthoOffCenterLH(m, 0.0f, (float)m_width, (float)m_height, 0.0f, -1e30f, 1e30f);
 			m = m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView->GetTop();
 			m_RP.m_TI[m_RP.m_nProcessThreadID].m_matView->LoadIdentity();
 
 			EF_SetColorOp(eCO_REPLACE, eCO_REPLACE, DEF_TEXARG0, DEF_TEXARG0);
 			STexState ts(FILTER_LINEAR, false);
 			ts.m_nAnisotropy = 1;
 			tp->Apply(0, CTexture::GetTexState(ts));
 			SetCullMode(R_CULL_NONE);
 
 			for (int iSide=0; iSide<6; iSide++)
 			{
 				uint32 nOffs;
 				SVF_P3F_T3F *vQuad = (SVF_P3F_T3F *)m_DynVB[POOL_P3F_TEX3F].LockVB(4, nOffs);
 				if (!vQuad)
 					return;
 
 				vQuad[0].p = Vec3(fOffsX[iSide], fOffsY[iSide], 1);
 				vQuad[0].st = vTC0[iSide];
 				vQuad[1].p = Vec3(fOffsX[iSide]+fSizeX-1, fOffsY[iSide], 1);
 				vQuad[1].st = vTC1[iSide];
 				vQuad[2].p = Vec3(fOffsX[iSide]+fSizeX-1, fOffsY[iSide]+fSizeY-1, 1);
 				vQuad[2].st = vTC2[iSide];
 				vQuad[3].p = Vec3(fOffsX[iSide], fOffsY[iSide]+fSizeY-1, 1);
 				vQuad[3].st = vTC3[iSide];
 
 				// We are finished with accessing the vertex buffer
 				m_DynVB[POOL_P3F_TEX3F].UnlockVB();
 
 				if (!FAILED(FX_SetVertexDeclaration(0, eVF_P3F_T3F)))
 				{
 					// Bind our vertex as the first data stream of our device
 					m_DynVB[POOL_P3F_TEX3F].Bind();
 					FX_SetFPMode();
 
 					// Render the two triangles from the data stream
 #if defined (DIRECT3D9)
 					HRESULT hReturn = m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN, nOffs, 2);
 					assert(SUCCEEDED(hReturn));
 #elif defined (DIRECT3D10)
 					assert(0);
 #endif
 				}
 			}
 			EF_PopMatrix();
 			m_RP.m_TI[m_RP.m_nProcessThreadID].m_matProj->Pop();
 		}
 		tp->m_nAccessFrameID = nSavedAccessFrameID;
 
 		const char *pTexName = tp->GetName();
 		char nameBuffer[128];
 		memset(nameBuffer, 0, sizeof nameBuffer);
 		for (int iStr = 0, jStr = 0; pTexName[iStr] && jStr < sizeof nameBuffer - 1; ++iStr)
 		{
 			if (pTexName[iStr] == '$')
 			{
 				nameBuffer[jStr] = '$';
 				nameBuffer[jStr + 1] = '$';
 				jStr += 2;
 			}
 			else
 			{
 				nameBuffer[jStr] = pTexName[iStr];
 				++jStr;
 			}
 		}
 		nameBuffer[sizeof nameBuffer - 1] = 0;
 		pTexName = nameBuffer;
 
 		int32 nPosX = (int32)ScaleCoordX(x);
 		int32 nPosY = (int32)ScaleCoordY(y);
 		_DrawText(iSystem, nPosX, nPosY, 1.0f, "%8s", pTexName);
 		_DrawText(iSystem, nPosX, nPosY+=10, 1.0f, "%d-%d", tp->m_nUpdateFrameID, tp->m_nAccessFrameID);
 		_DrawText(iSystem, nPosX, nPosY+=10, 1.0f, "%dx%d", tp->GetWidth(), tp->GetHeight());
  
 		if(bLogNames)
 		{
 			iLog->Log("Mem:%d  %dx%d  Type:%s  Format:%s (%s)",
 				tp->GetDeviceDataSize(),tp->GetWidth(), tp->GetHeight(),tp->NameForTextureType(tp->GetTextureType()), tp->NameForTextureFormat(tp->GetDstFormat()), tp->GetName());
 		}
 
 		x += fPicDimX;
 		if (x >= width-10)
 		{
 			x = 0;
 			y += fPicDimY;
 		}
 	}
 
 	Set2DMode(false, m_width, m_height);
 	
 	RT_FlushTextMessages(); 
 #endif
 }
 
 bool CFlashTextureSourceBase::Update(float /*distToCamera*/)
 {
 	// Maintenance: If to be changed please make according changes to CFlashTextureSource!
 
 	// sanity check: need player and some texture to draw to
 	SDynTexture* pDynTexture = GetDynTexture();
 
 	CryAutoCriticalSection lock(m_lock);
 
 	if (!m_pFlashPlayer)
 		return false;
 
 	assert(m_pFlashPlayer && pDynTexture);
 	if (!m_pFlashPlayer || !pDynTexture)
 		return false;
 
 	int rtWidth = GetWidth();
 	int rtHeight = GetHeight();
 	if (m_pUIElement)
 	{
 		if (m_pUIElement->HasFlag(IUIElement::eFUI_LAZY_UPDATE) && !m_pUIElement->NeedLazyRender())
 			return true;
 
 		m_pUIElement->LazyRendered();
 
 		int overrideWidth;
 		int overrideHeight;
 		if (m_pUIElement->GetDynTexSize(overrideWidth, overrideHeight))
 		{
 			rtWidth = max(Align8(overrideWidth),16);
 			rtHeight = max(Align8(overrideHeight),16);
 		}
 	}
 	bool needResize = rtWidth != pDynTexture->m_nWidth || rtHeight != pDynTexture->m_nHeight;
 	if (!pDynTexture->IsValid() || needResize)
 	{
 		if (!pDynTexture->Update(rtWidth, rtHeight))
 			return false;
 	}
 
 	m_width = rtWidth;
 	m_height = rtHeight;
 	m_aspectRatio = ((float) m_pFlashPlayer->GetWidth() / (float) m_width) * ((float) m_height / (float) m_pFlashPlayer->GetHeight());
 
 #if !defined(ENABLE_FLASH_LOCKLESS_RENDERING_API)
 	m_pFlashPlayer->SetViewport(0, 0, m_width, m_height, m_aspectRatio);
 	m_pFlashPlayer->SetScissorRect(0, 0, m_width, m_height);
 	m_pFlashPlayer->SetBackgroundAlpha(0.0f);
 #endif
 
 	PROFILE_LABEL_PUSH("FlashDynTextureSource SharedRT");
 
 	uint32 dynTexRectX = 0, dynTexRectY = 0, dynTexRectWidth = 0, dynTexRectHeight = 0;
 	pDynTexture->GetImageRect(dynTexRectX, dynTexRectY, dynTexRectWidth, dynTexRectHeight);
 	pDynTexture->m_pTexture->SetRenderTargetTile(1);
 	pDynTexture->SetRT(0, true, gcpRendD3D->FX_GetDepthSurface(dynTexRectWidth, dynTexRectHeight, false));
 	gcpRendD3D->RT_SetViewport(0, 0, rtWidth, rtHeight);
 #if defined(DIRECT3D10)
 	int clearFlags = FRT_CLEAR_COLOR | FRT_CLEAR_IMMEDIATE;
 #else
 	int clearFlags = FRT_CLEAR_COLOR;
 #endif
 	ColorF clearCol(0, 0, 0, 0);
 	gcpRendD3D->EF_ClearBuffers(clearFlags, &clearCol);
 	gcpRendD3D->FX_Commit(true);
 
 	if (m_bVisible)
 	{
 #if defined(ENABLE_FLASH_LOCKLESS_RENDERING_API)
 		m_pFlashPlayer->RenderPlaybackLockless(false, false);
 #else
 		m_pFlashPlayer->Render(false);
 #endif
 	}
 
 	pDynTexture->RestoreRT(0, true);
 	gcpRendD3D->FX_SetState(gcpRendD3D->m_RP.m_CurState & ~GS_BLEND_MASK);
 
 	pDynTexture->SetUpdateMask();
 
 	PROFILE_LABEL_POP("FlashDynTextureSource");
 
 	m_lastVisible = gEnv->pTimer->GetAsyncTime();
 #if !defined(ENABLE_FLASH_LOCKLESS_RENDERING_API)
 	m_lastVisibleFrameID = gRenDev->GetFrameID(false);
 #endif
 
 	return true;
 }
 
 bool CTexture::SaveDDS(const char *szName, bool bMips)
 {
 	if (!m_pDevTexture)
 		return false;
 	HRESULT hr = S_OK;
 #if defined (DIRECT3D9)
 
 
 
 
 
 
 	hr = D3DXSaveTextureToFile(szName, D3DXIFF_DDS, m_pDevTexture->Get2DTexture(), NULL);
 #elif defined (DIRECT3D10) && !defined(gringo)
 	hr = D3DX11SaveTextureToFile(gcpRendD3D->GetDeviceContext(), m_pDevTexture->Get2DTexture(), D3DX11_IFF_DDS, szName);
 #endif
 	return (hr == S_OK);
 }
 
 bool CTexture::SaveJPG(const char *szName, bool bMips)
 {
 	if (!m_pDevTexture)
 		return false;
 	HRESULT hr = S_OK;
 #if defined (DIRECT3D9)
 	D3DXSaveTextureToFile(szName, D3DXIFF_JPG, m_pDevTexture->Get2DTexture(), NULL);
 #elif defined (DIRECT3D10) && !defined(gringo)
 	hr = D3DX11SaveTextureToFile(gcpRendD3D->GetDeviceContext(), m_pDevTexture->Get2DTexture(), D3DX11_IFF_JPG, szName);
 #endif
 	return (hr == S_OK);
 }
 
 bool CTexture::SaveTGA(const char *szName, bool bMips)
 {
 	if (!m_pDevTexture)
 		return false;
 	HRESULT hr = S_OK;
 #if defined (DIRECT3D9)
 	hr = D3DXSaveTextureToFile(szName, D3DXIFF_TGA, m_pDevTexture->Get2DTexture(), NULL);
 #elif defined (DIRECT3D10) && !defined(gringo)
 	hr = D3DX11SaveTextureToFile(gcpRendD3D->GetDeviceContext(), m_pDevTexture->Get2DTexture(), D3DX11_IFF_TIFF, szName);
 #endif
 	return (hr == S_OK);
 }
 
 void CTexture::ReleaseSystemTargets()
 {
   CTexture::DestroyHDRMaps();
 	CTexture::DestroySceneMap();
 
   if (CDeferredShading::Instance().IsValid())
     CDeferredShading::Instance().DestroyDeferredMaps();
 
   SPostEffectsUtils::Release();
 
 	SAFE_RELEASE_FORCE(s_ptexWaterOcean);
 	SAFE_RELEASE_FORCE(s_ptexWaterVolumeTemp);
 	SAFE_RELEASE_FORCE(s_ptexWaterRipplesDDN);
 
   SAFE_RELEASE_FORCE(s_ptexSceneNormalsMap);
 	SAFE_RELEASE_FORCE(s_ptexSceneNormalsBent);
   SAFE_RELEASE_FORCE(s_ptexSceneDiffuseAccMap);
   SAFE_RELEASE_FORCE(s_ptexSceneSpecularAccMap);
 	SAFE_RELEASE_FORCE(s_ptexDeferredDecalTarget);
 	SAFE_RELEASE_FORCE(s_ptexBackBuffer); 
 	SAFE_RELEASE_FORCE(s_ptexSceneTarget);
 	SAFE_RELEASE_FORCE(s_ptexZTargetScaled);
 	SAFE_RELEASE_FORCE(s_ptexZTargetScaled2);
   SAFE_RELEASE_FORCE(s_ptexSceneUVsMap);
 
 	//#ifndef DIRECT3D10
 	//	SAFE_RELEASE_FORCE(s_ptexZTarget);
 	//#endif
 
 	gcpRendD3D->m_bSystemTargetsInit = 0;
 }
 
 void CTexture::ReleaseMiscTargets()
 {
 	if (gcpRendD3D->m_pColorGradingControllerD3D)
 		gcpRendD3D->m_pColorGradingControllerD3D->ReleaseTextures();
 }
 
 void CTexture::CreateSystemTargets()
 {
 	if( !gcpRendD3D->m_bSystemTargetsInit )
 	{
 		ScopedSwitchToGlobalHeap useGlobalHeap;
 
 		gcpRendD3D->m_bSystemTargetsInit = 1;
 
 		ETEX_Format eTF = (gcpRendD3D->m_RP.m_bUseHDR && gcpRendD3D->m_nHDRType==1) ? eTF_A16B16G16R16F : eTF_A8R8G8B8;
 
 
 
 
 
 		// Create HDR targets
 		CTexture::GenerateHDRMaps();
 
 		// Create scene targets
 		CTexture::GenerateSceneMap(eTF);
 		
 		// Create ZTarget
 
 
 
 		CTexture::GenerateZMaps();
 
 
 		// Create deferred lighting targets
 		if (CDeferredShading::Instance().IsValid())
 			CDeferredShading::Instance().CreateDeferredMaps();
 
 		// Create post effects targets
 		SPostEffectsUtils::Create();
 	}
 }
 #if !defined(XENON) && !defined(PS3)
 void CTexture::RT_Warmup()
 {
   CD3D9Renderer::C2dImage img(0, 0, 10, 10, NULL, 0, 0, 1, 1, 0, -1, 1, 0);
 
   SResourceContainer *pRL = CBaseResource::GetResourcesForClass(CTexture::mfGetClassName());
   if (pRL)
   {
     ResourcesMapItor itor;
     for (itor=pRL->m_RMap.begin(); itor!=pRL->m_RMap.end(); itor++)
     {
       CTexture *tp = (CTexture *)itor->second;
       if (!tp)
         continue;
       if (tp->IsStreamable())
         continue;
       if (!(tp->GetFlags() & FT_FROMIMAGE))
         continue;
       if (!tp->IsLoaded())
         continue;
       if (tp->IsNoTexture())
         continue;
       img.pTex = tp;
       if (tp->GetTexType() == eTT_2D)
       {
         // can currently only handle 2D textures (otherwise sampler is invalid which might cause freezes)
         // TODO: either support other texture types as well or better...
         // use precache points on PC to render the scene, this would also 100% activate shaders across IHVs
         gcpRendD3D->RT_Draw2dImageInternal(&img, 1);
       }
     }
   }
 }
 #endif
